diff options
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h')
-rw-r--r-- | Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h | 207 |
1 files changed, 154 insertions, 53 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h index 242ce44d3a6..f7bc57df233 100644 --- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h +++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h @@ -1,6 +1,6 @@ /* Uniform Interface to GMP. -Copyright 2004-2019 Free Software Foundation, Inc. +Copyright 2004-2020 Free Software Foundation, Inc. Contributed by the AriC and Caramba projects, INRIA. This file is part of the GNU MPFR Library. @@ -64,11 +64,15 @@ extern "C" { # 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" +#if (GMP_NUMB_BITS<8) || (GMP_NUMB_BITS & (GMP_NUMB_BITS - 1)) +# error "GMP_NUMB_BITS must be a power of 2, and >= 8" #endif -#if GMP_NUMB_BITS == 32 +#if GMP_NUMB_BITS == 8 +# define MPFR_LOG2_GMP_NUMB_BITS 3 +#elif 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 @@ -94,27 +98,6 @@ extern "C" { #else /* without gmp build (gmp-impl.h replacement) */ -/* 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 - /* Define some macros */ #define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1)) @@ -130,7 +113,9 @@ void *alloca (size_t); #define MP_SIZE_T_MIN LONG_MIN #endif -/* MP_LIMB macros */ +/* MP_LIMB macros. + Note: GMP now also has the MPN_FILL macro, and GMP's MPN_ZERO(dst,n) is + defined as "if (n) MPN_FILL(dst, n, 0);". */ #define MPN_ZERO(dst, n) memset((dst), 0, (n)*MPFR_BYTES_PER_MP_LIMB) #define MPN_COPY(dst,src,n) \ do \ @@ -177,6 +162,10 @@ void *alloca (size_t); #define MPN_SAME_OR_DECR_P(dst, src, size) \ MPN_SAME_OR_DECR2_P(dst, size, src, size) +#ifndef MUL_FFT_THRESHOLD +#define MUL_FFT_THRESHOLD 8448 +#endif + /* 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)) @@ -259,28 +248,6 @@ __MPFR_DECLSPEC extern const struct bases mpfr_bases[257]; #define MIN(l,o) ((l) < (o) ? (l) : (o)) #define MAX(h,i) ((h) > (i) ? (h) : (i)) -/* Size of an array, safe version but not a constant expression: - Since an array can silently be converted to a pointer, we check - that this macro is applied on an array, not a pointer. */ -#undef numberof -#if 0 -/* The following should work with GCC as documented in its manual, - but fails: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38377#c10 - Thus disabled for now. */ -# define numberof(x) \ - ( __extension__ ({ \ - int is_array = (void *) &(x) == (void *) &(x)[0]; \ - MPFR_STAT_STATIC_ASSERT (__builtin_constant_p (is_array) ? \ - is_array : 1); \ - MPFR_ASSERTN (is_array); \ - numberof_const (x); \ - }) ) -#else -# define numberof(x) \ - (MPFR_ASSERTN ((void *) &(x) == (void *) &(x)[0]), \ - numberof_const (x)) -#endif - __MPFR_DECLSPEC void * mpfr_allocate_func (size_t); __MPFR_DECLSPEC void * mpfr_reallocate_func (void *, size_t, size_t); __MPFR_DECLSPEC void mpfr_free_func (void *, size_t); @@ -298,7 +265,14 @@ __MPFR_DECLSPEC mp_limb_t __gmpn_invert_limb (mp_limb_t); #endif #endif -/* Temp memory allocate */ +#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_RSBLSH1_N) +#ifndef __gmpn_rsblsh1_n +__MPFR_DECLSPEC mp_limb_t __gmpn_rsblsh1_n (mp_limb_t*, mp_limb_t*, mp_limb_t*, mp_size_t); +#endif +#endif + +/* Definitions related to temporary memory allocation */ + struct tmp_marker { void *ptr; @@ -310,16 +284,62 @@ __MPFR_DECLSPEC void *mpfr_tmp_allocate (struct tmp_marker **, size_t); __MPFR_DECLSPEC void mpfr_tmp_free (struct tmp_marker *); -/* Can be overridden at configure time. Useful for checking buffer overflow. */ +/* Default MPFR_ALLOCA_MAX value. It can be overridden at configure time; + with some tools, by giving a low value such as 0, this is useful for + checking buffer overflow, which may not be possible with alloca. + If HAVE_ALLOCA is not defined, then alloca() is not available, so that + MPFR_ALLOCA_MAX needs to be 0 (see the definition of TMP_ALLOC below); + if the user has explicitly given a non-zero value, this will probably + yield an error at link time or at run time. */ #ifndef MPFR_ALLOCA_MAX -# define MPFR_ALLOCA_MAX 16384 +# ifdef HAVE_ALLOCA +# define MPFR_ALLOCA_MAX 16384 +# else +# define MPFR_ALLOCA_MAX 0 +# endif #endif /* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */ -#define TMP_ALLOC(n) (MPFR_LIKELY ((n) <= MPFR_ALLOCA_MAX) ? \ + +#if MPFR_ALLOCA_MAX != 0 + +/* 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? + But note that the HAVE_ALLOCA test in it seems wrong. + https://lists.gnu.org/archive/html/bug-autoconf/2019-01/msg00009.html */ +#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 + +#define TMP_ALLOC(n) (MPFR_ASSERTD ((n) > 0), \ + MPFR_LIKELY ((n) <= MPFR_ALLOCA_MAX) ? \ alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n))) + +#else /* MPFR_ALLOCA_MAX == 0, alloca() not needed */ + +#define TMP_ALLOC(n) (mpfr_tmp_allocate (&tmp_marker, (n))) + +#endif + #define TMP_DECL(m) struct tmp_marker *tmp_marker + #define TMP_MARK(m) (tmp_marker = 0) + /* Note about TMP_FREE: For small precisions, tmp_marker is null as the allocation is done on the stack (see TMP_ALLOC above). */ #define TMP_FREE(m) \ @@ -335,6 +355,84 @@ __MPFR_DECLSPEC void mpfr_tmp_free (struct tmp_marker *); ****** interfaces. ***** ******************************************************/ +#ifndef MPFR_LONG_WITHIN_LIMB + +/* the following routines assume that an unsigned long has at least twice the + size of an mp_limb_t */ + +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + unsigned long _p = (unsigned long) (m0) * (unsigned long) (m1); \ + (ph) = (mp_limb_t) (_p >> GMP_NUMB_BITS); \ + (pl) = (mp_limb_t) (_p & MPFR_LIMB_MAX); \ + } while (0) + +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + unsigned long _a = ((unsigned long) (ah) << GMP_NUMB_BITS) + (al); \ + unsigned long _b = ((unsigned long) (bh) << GMP_NUMB_BITS) + (bl); \ + unsigned long _s = _a + _b; \ + (sh) = (mp_limb_t) (_s >> GMP_NUMB_BITS); \ + (sl) = (mp_limb_t) (_s & MPFR_LIMB_MAX); \ + } while (0) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + unsigned long _a = ((unsigned long) (ah) << GMP_NUMB_BITS) + (al); \ + unsigned long _b = ((unsigned long) (bh) << GMP_NUMB_BITS) + (bl); \ + unsigned long _s = _a - _b; \ + (sh) = (mp_limb_t) (_s >> GMP_NUMB_BITS); \ + (sl) = (mp_limb_t) (_s & MPFR_LIMB_MAX); \ + } while (0) + +#define count_leading_zeros(count,x) \ + do { \ + int _c = 0; \ + mp_limb_t _x = (mp_limb_t) (x); \ + while (GMP_NUMB_BITS > 16 && (_x >> (GMP_NUMB_BITS - 16)) == 0) \ + { \ + _c += 16; \ + _x = (mp_limb_t) (_x << 16); \ + } \ + if (GMP_NUMB_BITS > 8 && (_x >> (GMP_NUMB_BITS - 8)) == 0) \ + { \ + _c += 8; \ + _x = (mp_limb_t) (_x << 8); \ + } \ + if (GMP_NUMB_BITS > 4 && (_x >> (GMP_NUMB_BITS - 4)) == 0) \ + { \ + _c += 4; \ + _x = (mp_limb_t) (_x << 4); \ + } \ + if (GMP_NUMB_BITS > 2 && (_x >> (GMP_NUMB_BITS - 2)) == 0) \ + { \ + _c += 2; \ + _x = (mp_limb_t) (_x << 2); \ + } \ + if ((_x & MPFR_LIMB_HIGHBIT) == 0) \ + _c ++; \ + (count) = _c; \ + } while (0) + +#define invert_limb(invxl,xl) \ + do { \ + unsigned long _num; \ + MPFR_ASSERTD ((xl) != 0); \ + _num = (unsigned long) (mp_limb_t) ~(xl); \ + _num = (_num << GMP_NUMB_BITS) | MPFR_LIMB_MAX; \ + (invxl) = _num / (xl); \ + } while (0) + +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { \ + unsigned long _num; \ + _num = ((unsigned long) (n1) << GMP_NUMB_BITS) | (n0); \ + (q) = _num / (d); \ + (r) = _num % (d); \ + } while (0) + +#endif + /* If mpn_sqr is not defined, use mpn_mul_n instead (mpn_sqr was called mpn_sqr_n (internal) in older versions of GMP). */ #ifndef mpn_sqr @@ -399,7 +497,10 @@ __MPFR_DECLSPEC void mpfr_tmp_free (struct tmp_marker *); } while (0) #endif -/* invert_pi1 macro adapted from GMP 5 */ +/* invert_pi1 macro adapted from GMP 5, this computes in (dinv).inv32 + the value of floor((beta^3 - 1)/(d1*beta+d0)) - beta, + cf "Improved Division by Invariant Integers" by Niels Möller and + Torbjörn Granlund */ typedef struct {mp_limb_t inv32;} mpfr_pi1_t; #ifndef invert_pi1 #define invert_pi1(dinv, d1, d0) \ |