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 | 412 |
1 files changed, 412 insertions, 0 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 new file mode 100644 index 00000000000..b1862ffe717 --- /dev/null +++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h @@ -0,0 +1,412 @@ +/* Interface to replace gmp-impl.h + +Copyright 2004-2015 Free Software Foundation, Inc. +Contributed by the AriC and Caramel projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, 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 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)*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 \ + { \ + if ((dst) != (src)) \ + { \ + MPFR_ASSERTD ((char *) (dst) >= (char *) (src) + \ + (n) * MPFR_BYTES_PER_MP_LIMB || \ + (char *) (src) >= (char *) (dst) + \ + (n) * MPFR_BYTES_PER_MP_LIMB); \ + memcpy ((dst), (src), (n) * MPFR_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 \ + ((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)); + +#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 */ |