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 | 552 |
1 files changed, 392 insertions, 160 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 850e0d396db..a4c13aa4125 100644 --- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h +++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h @@ -1,4 +1,4 @@ -/* Interface to replace gmp-impl.h +/* Uniform Interface to GMP. Copyright 2004-2017 Free Software Foundation, Inc. Contributed by the AriC and Caramba projects, INRIA. @@ -27,8 +27,75 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., # error "mpfr-impl.h not included" #endif -#include <limits.h> /* For INT_MAX, ... */ -#include <string.h> /* For memcpy, memset and memmove */ + +/****************************************************** + ******************** C++ Compatibility *************** + ******************************************************/ +#if defined (__cplusplus) +extern "C" { +#endif + + +/****************************************************** + ******************** Identify GMP ******************** + ******************************************************/ + +/* Macro to detect the GMP version */ +#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 + + + +/****************************************************** + ******************** Check GMP *********************** + ******************************************************/ + +#if !__MPFR_GMP(5,0,0) && !defined(MPFR_USE_MINI_GMP) +# error "GMP 5.0.0 or newer is required" +#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 == 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 + +/* Remap names of internal mpn functions (for longlong.h). + Note: this should be made both with and without gmp build. */ +#undef __clz_tab +#define __clz_tab mpfr_clz_tab + +/****************************************************** + ************* Define GMP Internal Interface ********* + ******************************************************/ + +#ifdef MPFR_HAVE_GMP_IMPL /* with gmp build */ + +#define mpfr_allocate_func (*__gmp_allocate_func) +#define mpfr_reallocate_func (*__gmp_reallocate_func) +#define mpfr_free_func (*__gmp_free_func) + +#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 */ @@ -51,36 +118,12 @@ 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 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 @@ -90,14 +133,8 @@ extern "C" { #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)*MPFR_BYTES_PER_MP_LIMB) -#define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB) -#define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB) #define MPN_COPY(dst,src,n) \ do \ { \ @@ -152,24 +189,27 @@ extern "C" { #endif /* ASSERT */ -__MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int, - const char *)); +__MPFR_DECLSPEC void mpfr_assert_fail (const char *, int, + const char *); #define ASSERT_FAIL(expr) mpfr_assert_fail (__FILE__, __LINE__, #expr) +/* ASSERT() is for mpfr-longlong.h only. */ #define ASSERT(expr) MPFR_ASSERTD(expr) /* Access fields of GMP struct */ #define SIZ(x) ((x)->_mp_size) #define ABSIZ(x) ABS (SIZ (x)) #define PTR(x) ((x)->_mp_d) +#define ALLOC(x) ((x)->_mp_alloc) +/* For mpf numbers only. */ +#ifdef MPFR_NEED_MPF_INTERNALS +/* Note: the EXP macro name is reserved when <errno.h> is included. + For compatibility with gmp-impl.h (cf --with-gmp-build), we cannot + change this macro, but let's define it only when we need it, where + <errno.h> will not be included. */ #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 +#endif /* For longlong.h */ #ifdef HAVE_ATTRIBUTE_MODE @@ -194,14 +234,10 @@ 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))) +#define MP_BASE_AS_DOUBLE (4.0 * (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 2))) /* Structure for conversion between internal binary format and strings in base 2..36. */ @@ -218,89 +254,50 @@ __MPFR_DECLSPEC extern const struct bases mpfr_bases[257]; #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) - -/* 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 \ - ((void) (MPFR_LIKELY (mpfr_allocate_func != 0) || \ - (mp_get_memory_functions(&mpfr_allocate_func, \ - &mpfr_reallocate_func, \ - &mpfr_free_func), 1))) -#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 MPFR_THREAD_ATTR void * (*mpfr_allocate_func) _MPFR_PROTO ((size_t)); -__MPFR_DECLSPEC extern MPFR_THREAD_ATTR void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *, size_t, size_t)); -__MPFR_DECLSPEC extern MPFR_THREAD_ATTR void (*mpfr_free_func) _MPFR_PROTO ((void *, size_t)); +/* 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 -#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 +__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); #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)); +__MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q (mp_limb_t*, + mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t); #endif #endif -/* Temp memory allocate */ +#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB) +#ifndef __gmpn_invert_limb +__MPFR_DECLSPEC mp_limb_t __gmpn_invert_limb (mp_limb_t); +#endif +#endif +/* Temp memory allocate */ struct tmp_marker { void *ptr; @@ -308,62 +305,59 @@ struct tmp_marker 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 *)); +__MPFR_DECLSPEC void *mpfr_tmp_allocate (struct tmp_marker **, + size_t); +__MPFR_DECLSPEC void mpfr_tmp_free (struct tmp_marker *); + +/* Can be overriden at configure time. Useful for checking buffer overflow. */ +#ifndef MPFR_ALLOCA_MAX +# define MPFR_ALLOCA_MAX 16384 +#endif /* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */ -#define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ? \ +#define TMP_ALLOC(n) (MPFR_LIKELY ((n) <= MPFR_ALLOCA_MAX) ? \ 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) +/* 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) \ + (MPFR_LIKELY (tmp_marker == NULL) ? (void) 0 : mpfr_tmp_free (tmp_marker)) + +#endif /* gmp-impl.h replacement */ + + + +/****************************************************** + ****** GMP Interface which changes with versions ***** + ****** to other versions of GMP. Add missing ***** + ****** interfaces. ***** + ******************************************************/ + +/* 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 +# define mpn_sqr(dst,src,n) mpn_mul_n((dst),(src),(src),(n)) +#endif /* 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 +#ifndef invert_limb +#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_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); \ + invxl = __gmpn_invert_limb (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; \ +#else +#define invert_limb(invxl,xl) \ + do { \ + mp_limb_t dummy MPFR_MAYBE_UNUSED; \ + MPFR_ASSERTD ((xl) != 0); \ + udiv_qrnnd (invxl, dummy, ~(xl), MPFR_LIMB_MAX, xl); \ } while (0) +#endif /* defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB) */ +#endif /* ifndef invert_limb */ /* 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 @@ -374,7 +368,7 @@ typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into NOTE: Output variables are updated multiple times. Only some inputs and outputs may overlap. */ -#undef udiv_qr_3by2 +#ifndef udiv_qr_3by2 #define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \ do { \ mp_limb_t _q0, _t1, _t0, _mask; \ @@ -402,7 +396,245 @@ typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into } \ } \ } while (0) +#endif + +/* invert_pi1 macro adapted from GMP 5 */ +typedef struct {mp_limb_t inv32;} mpfr_pi1_t; +#ifndef 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 = -(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 (MPFR_UNLIKELY (_p >= (d1))) \ + { \ + if (_p > (d1) || _t0 >= (d0)) \ + _v--; \ + } \ + } \ + (dinv).inv32 = _v; \ + } while (0) +#endif + +/* The following macro is copied from GMP-6.1.1, file gmp-impl.h, + macro udiv_qrnnd_preinv. + It computes q and r such that nh*2^GMP_NUMB_BITS + nl = q*d + r, + with 0 <= r < d, assuming di = __gmpn_invert_limb (d). */ +#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 (MPFR_UNLIKELY (_r >= (d))) \ + { \ + _r -= (d); \ + _qh++; \ + } \ + } \ + (r) = _r; \ + (q) = _qh; \ + } while (0) + +#if GMP_NUMB_BITS == 64 +/* specialized version for nl = 0, with di computed inside */ +#define __udiv_qrnd_preinv(q, r, nh, d) \ + do { \ + mp_limb_t _di; \ + \ + MPFR_ASSERTD ((d) != 0); \ + MPFR_ASSERTD ((nh) < (d)); \ + MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \ + \ + __gmpfr_invert_limb (_di, d); \ + __udiv_qrnnd_preinv (q, r, nh, 0, d, _di); \ + } while (0) +#elif defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB) +/* specialized version for nl = 0, with di computed inside */ +#define __udiv_qrnd_preinv(q, r, nh, d) \ + do { \ + mp_limb_t _di; \ + \ + MPFR_ASSERTD ((d) != 0); \ + MPFR_ASSERTD ((nh) < (d)); \ + MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \ + \ + _di = __gmpn_invert_limb (d); \ + __udiv_qrnnd_preinv (q, r, nh, 0, d, _di); \ + } while (0) +#else +/* Same as __udiv_qrnnd_c from longlong.h, but using a single UWType/UWtype + division instead of two, and with n0=0. The analysis below assumes a limb + has 64 bits for simplicity. */ +#define __udiv_qrnd_preinv(q, r, n1, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0, __r1, __r0, __i; \ + \ + MPFR_ASSERTD ((d) != 0); \ + MPFR_ASSERTD ((n1) < (d)); \ + MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \ + \ + __d1 = __ll_highpart (d); \ + /* 2^31 <= d1 < 2^32 */ \ + __d0 = __ll_lowpart (d); \ + /* 0 <= d0 < 2^32 */ \ + __i = ~(UWtype) 0 / __d1; \ + /* 2^32 < i < 2^33 with i < 2^64/d1 */ \ + \ + __q1 = (((n1) / __ll_B) * __i) / __ll_B; \ + /* Since n1 < d, high(n1) <= d1 = high(d), thus */ \ + /* q1 <= high(n1) * (2^64/d1) / 2^32 <= 2^32 */ \ + /* and also q1 <= n1/d1 thus r1 >= 0 below */ \ + __r1 = (n1) - __q1 * __d1; \ + while (__r1 >= __d1) \ + __q1 ++, __r1 -= __d1; \ + /* by construction, we have n1 = q1*d1+r1, and 0 <= r1 < d1 */ \ + /* thus q1 <= n1/d1 < 2^32+2 */ \ + /* q1*d0 <= (2^32+1)*(2^32-1) <= 2^64-1 thus it fits in a limb. */ \ + __r0 = __r1 * __ll_B; \ + __r1 = __r0 - __q1 * __d0; \ + /* At most two corrections are needed like in __udiv_qrnnd_c. */ \ + if (__r1 > __r0) /* borrow when subtracting q1*d0 */ \ + { \ + __q1--, __r1 += (d); \ + if (__r1 > (d)) /* no carry when adding d */ \ + __q1--, __r1 += (d); \ + } \ + /* We can have r1 < m here, but in this case the true remainder */ \ + /* is 2^64+r1, which is > m (same analysis as below for r0). */ \ + /* Now we have n1*2^32 = q1*d + r1, with 0 <= r1 < d. */ \ + MPFR_ASSERTD(__r1 < (d)); \ + \ + /* The same analysis as above applies, with n1 replaced by r1, */ \ + /* q1 by q0, r1 by r0. */ \ + __q0 = ((__r1 / __ll_B) * __i) / __ll_B; \ + __r0 = __r1 - __q0 * __d1; \ + while (__r0 >= __d1) \ + __q0 ++, __r0 -= __d1; \ + __r1 = __r0 * __ll_B; \ + __r0 = __r1 - __q0 * __d0; \ + /* We know the quotient floor(r1*2^64/d) is q0, q0-1 or q0-2.*/ \ + if (__r0 > __r1) /* borrow when subtracting q0*d0 */ \ + { \ + /* The quotient is either q0-1 or q0-2. */ \ + __q0--, __r0 += (d); \ + if (__r0 > (d)) /* no carry when adding d */ \ + __q0--, __r0 += (d); \ + } \ + /* Now we have n1*2^64 = (q1*2^32+q0)*d + r0, with 0 <= r0 < d. */ \ + MPFR_ASSERTD(__r0 < (d)); \ + \ + (q) = __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) +#endif + +/****************************************************** + ************* GMP Basic Pointer Types **************** + ******************************************************/ + +typedef mp_limb_t *mpfr_limb_ptr; +typedef const mp_limb_t *mpfr_limb_srcptr; + +/* mpfr_ieee_double_extract structure (copied from GMP 6.1.0, gmp-impl.h, with + ieee_double_extract changed into mpfr_ieee_double_extract, and + _GMP_IEEE_FLOATS changed into _MPFR_IEEE_FLOATS). */ + +/* Define mpfr_ieee_double_extract and _MPFR_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. */ + +/* Note for MPFR: building with "gcc -std=c89 -pedantic -pedantic-errors" + fails if the bit-field type is unsigned long: + + error: type of bit-field '...' is a GCC extension [-Wpedantic] + + Though with -std=c99 no errors are obtained, this is still an extension + in C99, which says: + + A bit-field shall have a type that is a qualified or unqualified version + of _Bool, signed int, unsigned int, or some other implementation-defined + type. + + So, unsigned int should be better. This will fail with implementations + having 16-bit int's, but such implementations are not required to + support bit-fields of size > 16 anyway; if ever an implementation with + 16-bit int's is found, the appropriate minimal changes could still be + done in the future. +*/ + +#ifndef _MPFR_IEEE_FLOATS + +#ifdef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN +#define _MPFR_IEEE_FLOATS 1 +union mpfr_ieee_double_extract +{ + struct + { + unsigned int manl:32; + unsigned int manh:20; + unsigned int exp:11; + unsigned int sig:1; + } s; + double d; +}; +#endif + +#ifdef HAVE_DOUBLE_IEEE_BIG_ENDIAN +#define _MPFR_IEEE_FLOATS 1 +union mpfr_ieee_double_extract +{ + struct + { + unsigned int sig:1; + unsigned int exp:11; + unsigned int manh:20; + unsigned int manl:32; + } s; + double d; +}; +#endif + +#endif /* _MPFR_IEEE_FLOATS */ +/****************************************************** + ******************** C++ Compatibility *************** + ******************************************************/ #if defined (__cplusplus) } #endif |