Upgrade MPFR from 2.4.2-p3 to 3.1.0 on the vendor branch
[dragonfly.git] / contrib / mpfr / src / mpfr-gmp.h
1 /* Interface to replace gmp-impl.h
2
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Caramel projects, INRIA.
5
6 This file is part of the GNU MPFR Library.
7
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23 #ifndef __GMPFR_GMP_H__
24 #define __GMPFR_GMP_H__
25
26 #ifndef __MPFR_IMPL_H__
27 # error  "mpfr-impl.h not included"
28 #endif
29
30 #include <limits.h> /* For INT_MAX, ... */
31 #include <string.h> /* For memcpy, memset and memmove */
32
33 /* The following tries to get a good version of alloca.
34    See gmp-impl.h for implementation details and original version */
35 /* FIXME: the autoconf manual gives a different piece of code under the
36    documentation of the AC_FUNC_ALLOCA macro. Should we switch to it? */
37 #ifndef alloca
38 # if defined ( __GNUC__ )
39 #  define alloca __builtin_alloca
40 # elif defined (__DECC)
41 #  define alloca(x) __ALLOCA(x)
42 # elif defined (_MSC_VER)
43 #  include <malloc.h>
44 #  define alloca _alloca
45 # elif defined (HAVE_ALLOCA_H)
46 #  include <alloca.h>
47 # elif defined (_AIX) || defined (_IBMR2)
48 #  pragma alloca
49 # else
50 void *alloca (size_t);
51 # endif
52 #endif
53
54 #if defined (__cplusplus)
55 extern "C" {
56 #endif
57
58 /* Define GMP_NUMB_BITS
59    Can't use sizeof(mp_limb_t) since it should be a preprocessor constant */
60 #if defined(GMP_NUMB_BITS) /* GMP 4.1.2 or above */
61 #ifndef GMP_NUMB_BITS
62 # define GMP_NUMB_BITS  (GMP_NUMB_BITS+GMP_NAIL_BITS)
63 #endif
64 #elif defined (__GMP_GMP_NUMB_BITS) /* Older versions 4.x.x */
65 # define GMP_NUMB_BITS  __GMP_GMP_NUMB_BITS
66 # define GMP_NUMB_BITS GMP_NUMB_BITS
67 # ifndef GMP_NAIL_BITS
68 #  define GMP_NAIL_BITS 0
69 # endif
70 #else
71 # error "Could not detect GMP_NUMB_BITS. Try with gmp internal files."
72 #endif
73
74 /* Define some macros */
75 #define BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
76
77 #define MP_LIMB_T_MAX (~(mp_limb_t)0)
78
79 #define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1))
80 #define UINT_HIGHBIT  (UINT_MAX ^ ((unsigned) UINT_MAX >> 1))
81 #define USHRT_HIGHBIT ((unsigned short) (USHRT_MAX ^ ((unsigned short) USHRT_MAX >> 1)))
82
83 #define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
84
85
86 #if __GMP_MP_SIZE_T_INT
87 #define MP_SIZE_T_MAX      INT_MAX
88 #define MP_SIZE_T_MIN      INT_MIN
89 #else
90 #define MP_SIZE_T_MAX      LONG_MAX
91 #define MP_SIZE_T_MIN      LONG_MIN
92 #endif
93
94 #define LONG_HIGHBIT       LONG_MIN
95 #define INT_HIGHBIT        INT_MIN
96 #define SHRT_HIGHBIT       SHRT_MIN
97
98 /* MP_LIMB macros */
99 #define MPN_ZERO(dst, n) memset((dst), 0, (n)*BYTES_PER_MP_LIMB)
100 #define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
101 #define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
102 #define MPN_COPY(dst,src,n) \
103   do                                                                  \
104     {                                                                 \
105       if ((dst) != (src))                                             \
106         {                                                             \
107           MPFR_ASSERTD ((char *) (dst) >= (char *) (src) +            \
108                                           (n) * BYTES_PER_MP_LIMB ||  \
109                         (char *) (src) >= (char *) (dst) +            \
110                                           (n) * BYTES_PER_MP_LIMB);   \
111           memcpy ((dst), (src), (n) * BYTES_PER_MP_LIMB);             \
112         }                                                             \
113     }                                                                 \
114   while (0)
115
116 /* MPN macros taken from gmp-impl.h */
117 #define MPN_NORMALIZE(DST, NLIMBS) \
118   do {                                        \
119     while (NLIMBS > 0)                        \
120       {                                       \
121         if ((DST)[(NLIMBS) - 1] != 0)         \
122           break;                              \
123         NLIMBS--;                             \
124       }                                       \
125   } while (0)
126 #define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS)     \
127   do {                                          \
128     MPFR_ASSERTD ((NLIMBS) >= 1);               \
129     while (1)                                   \
130       {                                         \
131         if ((DST)[(NLIMBS) - 1] != 0)           \
132           break;                                \
133         NLIMBS--;                               \
134       }                                         \
135   } while (0)
136 #define MPN_OVERLAP_P(xp, xsize, yp, ysize) \
137   ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp))
138 #define MPN_SAME_OR_INCR2_P(dst, dsize, src, ssize)             \
139   ((dst) <= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
140 #define MPN_SAME_OR_INCR_P(dst, src, size)      \
141   MPN_SAME_OR_INCR2_P(dst, size, src, size)
142 #define MPN_SAME_OR_DECR2_P(dst, dsize, src, ssize)             \
143   ((dst) >= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
144 #define MPN_SAME_OR_DECR_P(dst, src, size)      \
145   MPN_SAME_OR_DECR2_P(dst, size, src, size)
146
147 /* If mul_basecase or mpn_sqr_basecase are not exported, used mpn_mul instead */
148 #ifndef mpn_mul_basecase
149 # define mpn_mul_basecase(dst,s1,n1,s2,n2) mpn_mul((dst),(s1),(n1),(s2),(n2))
150 #endif
151 #ifndef mpn_sqr_basecase
152 # define mpn_sqr_basecase(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
153 #endif
154
155 /* ASSERT */
156 __MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int,
157                                                    const char *));
158
159 #define ASSERT_FAIL(expr)  mpfr_assert_fail (__FILE__, __LINE__, #expr)
160 #define ASSERT(expr)       MPFR_ASSERTD(expr)
161
162 /* Access fileds of GMP struct */
163 #define SIZ(x) ((x)->_mp_size)
164 #define ABSIZ(x) ABS (SIZ (x))
165 #define PTR(x) ((x)->_mp_d)
166 #define LIMBS(x) ((x)->_mp_d)
167 #define EXP(x) ((x)->_mp_exp)
168 #define PREC(x) ((x)->_mp_prec)
169 #define ALLOC(x) ((x)->_mp_alloc)
170 #define MPZ_REALLOC(z,n) ((n) > ALLOC(z) ? _mpz_realloc(z,n) : PTR(z))
171
172 /* Non IEEE float supports -- needs to detect them with proper configure */
173 #undef  XDEBUG
174 #define XDEBUG
175
176 /* For longlong.h */
177 #ifdef HAVE_ATTRIBUTE_MODE
178 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
179 typedef          int SItype     __attribute__ ((mode (SI)));
180 typedef unsigned int USItype    __attribute__ ((mode (SI)));
181 typedef          int DItype     __attribute__ ((mode (DI)));
182 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
183 #else
184 typedef unsigned char UQItype;
185 typedef          long SItype;
186 typedef unsigned long USItype;
187 #ifdef HAVE_LONG_LONG
188 typedef long long int DItype;
189 typedef unsigned long long int UDItype;
190 #else /* Assume `long' gives us a wide enough type.  Needed for hppa2.0w.  */
191 typedef long int DItype;
192 typedef unsigned long int UDItype;
193 #endif
194 #endif
195 typedef mp_limb_t UWtype;
196 typedef unsigned int UHWtype;
197 #define W_TYPE_SIZE GMP_NUMB_BITS
198
199 /* Remap names of internal mpn functions (for longlong.h).  */
200 #undef  __clz_tab
201 #define __clz_tab               mpfr_clz_tab
202
203 /* Use (4.0 * ...) instead of (2.0 * ...) to work around buggy compilers
204    that don't convert ulong->double correctly (eg. SunOS 4 native cc).  */
205 #undef MP_BASE_AS_DOUBLE
206 #define MP_BASE_AS_DOUBLE (4.0 * ((mp_limb_t) 1 << (GMP_NUMB_BITS - 2)))
207
208 /* Structure for conversion between internal binary format and
209    strings in base 2..36.  */
210 struct bases
211 {
212   /* log(2)/log(conversion_base) */
213   double chars_per_bit_exactly;
214 };
215 #undef  __mp_bases
216 #define __mp_bases mpfr_bases
217 __MPFR_DECLSPEC extern const struct bases mpfr_bases[257];
218
219 /* Standard macros */
220 #undef ABS
221 #undef MIN
222 #undef MAX
223 #undef numberof
224 #define ABS(x) ((x) >= 0 ? (x) : -(x))
225 #define MIN(l,o) ((l) < (o) ? (l) : (o))
226 #define MAX(h,i) ((h) > (i) ? (h) : (i))
227 #define numberof(x)  (sizeof (x) / sizeof ((x)[0]))
228
229 /* Random */
230 #undef  __gmp_rands_initialized
231 #undef  __gmp_rands
232 #define __gmp_rands_initialized mpfr_rands_initialized
233 #define __gmp_rands             mpfr_rands
234
235 __MPFR_DECLSPEC extern char             mpfr_rands_initialized;
236 __MPFR_DECLSPEC extern gmp_randstate_t  mpfr_rands;
237
238 #undef RANDS
239 #define RANDS                                   \
240   ((__gmp_rands_initialized ? 0                 \
241     : (__gmp_rands_initialized = 1,             \
242        gmp_randinit_default (__gmp_rands), 0)), \
243    __gmp_rands)
244
245 #undef RANDS_CLEAR
246 #define RANDS_CLEAR()                   \
247   do {                                  \
248     if (__gmp_rands_initialized)        \
249       {                                 \
250         __gmp_rands_initialized = 0;    \
251         gmp_randclear (__gmp_rands);    \
252       }                                 \
253   } while (0)
254
255 typedef __gmp_randstate_struct *gmp_randstate_ptr;
256
257 /* Allocate func are defined in gmp-impl.h */
258
259 /* In newer GMP, there aren't anymore __gmp_allocate_func,
260    __gmp_reallocate_func & __gmp_free_func in gmp.h
261    Just getting the correct value by calling mp_get_memory_functions */
262 #ifdef mp_get_memory_functions
263
264 #undef __gmp_allocate_func
265 #undef __gmp_reallocate_func
266 #undef __gmp_free_func
267 #define MPFR_GET_MEMFUNC mp_get_memory_functions(&mpfr_allocate_func, &mpfr_reallocate_func, &mpfr_free_func)
268 #define __gmp_allocate_func   (MPFR_GET_MEMFUNC, mpfr_allocate_func)
269 #define __gmp_reallocate_func (MPFR_GET_MEMFUNC, mpfr_reallocate_func)
270 #define __gmp_free_func       (MPFR_GET_MEMFUNC, mpfr_free_func)
271 __MPFR_DECLSPEC extern void * (*mpfr_allocate_func)   _MPFR_PROTO ((size_t));
272 __MPFR_DECLSPEC extern void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *,
273                                                           size_t, size_t));
274 __MPFR_DECLSPEC extern void   (*mpfr_free_func)       _MPFR_PROTO ((void *,
275                                                                     size_t));
276
277 #endif
278
279 #undef __gmp_default_allocate
280 #undef __gmp_default_reallocate
281 #undef __gmp_default_free
282 #define __gmp_default_allocate   mpfr_default_allocate
283 #define __gmp_default_reallocate mpfr_default_reallocate
284 #define __gmp_default_free       mpfr_default_free
285 __MPFR_DECLSPEC void *__gmp_default_allocate _MPFR_PROTO ((size_t));
286 __MPFR_DECLSPEC void *__gmp_default_reallocate _MPFR_PROTO ((void *, size_t,
287                                                              size_t));
288 __MPFR_DECLSPEC void __gmp_default_free _MPFR_PROTO ((void *, size_t));
289
290 #if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
291 #ifndef __gmpn_rootrem
292   __MPFR_DECLSPEC mp_size_t __gmpn_rootrem _MPFR_PROTO ((mp_limb_t*,
293                     mp_limb_t*, mp_limb_t*, mp_size_t, mp_limb_t));
294 #endif
295 #endif
296
297 #if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
298 #ifndef __gmpn_sbpi1_divappr_q
299   __MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q _MPFR_PROTO ((mp_limb_t*,
300                 mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t));
301 #endif
302 #endif
303
304 /* Temp memory allocate */
305
306 struct tmp_marker
307 {
308   void *ptr;
309   size_t size;
310   struct tmp_marker *next;
311 };
312
313 __MPFR_DECLSPEC void *mpfr_tmp_allocate _MPFR_PROTO ((struct tmp_marker **,
314                                                       size_t));
315 __MPFR_DECLSPEC void mpfr_tmp_free _MPFR_PROTO ((struct tmp_marker *));
316
317 /* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */
318 #define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ?       \
319                       alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n)))
320 #define TMP_DECL(m) struct tmp_marker *tmp_marker
321 #define TMP_MARK(m) (tmp_marker = 0)
322 #define TMP_FREE(m) mpfr_tmp_free (tmp_marker)
323
324 /* invert_limb macro, copied from GMP 5.0.2, file gmp-impl.h.
325    It returns invxl = floor((B^2-1)/xl)-B, where B=2^BITS_PER_LIMB,
326    assuming the most significant bit of xl is set. */
327 #undef invert_limb
328 #define invert_limb(invxl,xl)                             \
329   do {                                                    \
330     mp_limb_t dummy;                                      \
331     MPFR_ASSERTD ((xl) != 0);                             \
332     udiv_qrnnd (invxl, dummy, ~(xl), ~(mp_limb_t)0, xl);  \
333   } while (0)
334
335 typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
336                                                  mpfr_pi1_t to avoid using
337                                                  GMP's namespace. */
338 /* invert_pi1 macro, adapted from GMP 5.0.2, file gmp-impl.h.
339    It returns dinv = floor((B^3-1)/(d1*B+d0))-B, where B=2^BITS_PER_LIMB,
340    assuming the most significant bit of d1 is set. */
341 #undef invert_pi1
342 #define invert_pi1(dinv, d1, d0)                                \
343   do {                                                          \
344     mp_limb_t _v, _p, _t1, _t0, _mask;                          \
345     invert_limb (_v, d1);                                       \
346     _p = d1 * _v;                                               \
347     _p += d0;                                                   \
348     if (_p < d0)                                                \
349       {                                                         \
350         _v--;                                                   \
351         _mask = -(_p >= d1);                                    \
352         _p -= d1;                                               \
353         _v += _mask;                                            \
354         _p -= _mask & d1;                                       \
355       }                                                         \
356     umul_ppmm (_t1, _t0, d0, _v);                               \
357     _p += _t1;                                                  \
358     if (_p < _t1)                                               \
359       {                                                         \
360         _v--;                                                   \
361         if (MPFR_UNLIKELY (_p >= d1))                           \
362           {                                                     \
363             if (_p > d1 || _t0 >= d0)                           \
364               _v--;                                             \
365           }                                                     \
366       }                                                         \
367     (dinv).inv32 = _v;                                          \
368   } while (0)
369
370 /* udiv_qr_3by2 macro, adapted from GMP 5.0.2, file gmp-impl.h.
371    Compute quotient the quotient and remainder for n / d. Requires d
372    >= B^2 / 2 and n < d B. dinv is the inverse
373
374      floor ((B^3 - 1) / (d0 + d1 B)) - B.
375
376    NOTE: Output variables are updated multiple times. Only some inputs
377    and outputs may overlap.
378 */
379 #undef udiv_qr_3by2
380 #define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv)               \
381   do {                                                                  \
382     mp_limb_t _q0, _t1, _t0, _mask;                                     \
383     umul_ppmm ((q), _q0, (n2), (dinv));                                 \
384     add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1));                        \
385                                                                         \
386     /* Compute the two most significant limbs of n - q'd */             \
387     (r1) = (n1) - (d1) * (q);                                           \
388     (r0) = (n0);                                                        \
389     sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0));                    \
390     umul_ppmm (_t1, _t0, (d0), (q));                                    \
391     sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0);                      \
392     (q)++;                                                              \
393                                                                         \
394     /* Conditionally adjust q and the remainders */                     \
395     _mask = - (mp_limb_t) ((r1) >= _q0);                                \
396     (q) += _mask;                                                       \
397     add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0));    \
398     if (MPFR_UNLIKELY ((r1) >= (d1)))                                   \
399       {                                                                 \
400         if ((r1) > (d1) || (r0) >= (d0))                                \
401           {                                                             \
402             (q)++;                                                      \
403             sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0));            \
404           }                                                             \
405       }                                                                 \
406   } while (0)
407
408 #if defined (__cplusplus)
409 }
410 #endif
411
412 #endif /* Gmp internal emulator */