hammer - Adjust hammer to new breadnx / cluster_readx API
[dragonfly.git] / contrib / mpfr / src / mpfr-gmp.h
blobc004fe5bb8b27b01ca14921e0ace35a1e4db87cf
1 /* Interface to replace gmp-impl.h
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
6 This file is part of the GNU MPFR Library.
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.
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.
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. */
23 #ifndef __GMPFR_GMP_H__
24 #define __GMPFR_GMP_H__
26 #ifndef __MPFR_IMPL_H__
27 # error "mpfr-impl.h not included"
28 #endif
30 #include <limits.h> /* For INT_MAX, ... */
31 #include <string.h> /* For memcpy, memset and memmove */
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
54 #if defined (__cplusplus)
55 extern "C" {
56 #endif
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
74 /* Define some macros */
75 #define BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
77 #define MP_LIMB_T_MAX (~(mp_limb_t)0)
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)))
83 #define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
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
94 #define LONG_HIGHBIT LONG_MIN
95 #define INT_HIGHBIT INT_MIN
96 #define SHRT_HIGHBIT SHRT_MIN
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 \
105 if ((dst) != (src)) \
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); \
114 while (0)
116 /* MPN macros taken from gmp-impl.h */
117 #define MPN_NORMALIZE(DST, NLIMBS) \
118 do { \
119 while (NLIMBS > 0) \
121 if ((DST)[(NLIMBS) - 1] != 0) \
122 break; \
123 NLIMBS--; \
125 } while (0)
126 #define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
127 do { \
128 MPFR_ASSERTD ((NLIMBS) >= 1); \
129 while (1) \
131 if ((DST)[(NLIMBS) - 1] != 0) \
132 break; \
133 NLIMBS--; \
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)
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
155 /* ASSERT */
156 __MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int,
157 const char *));
159 #define ASSERT_FAIL(expr) mpfr_assert_fail (__FILE__, __LINE__, #expr)
160 #define ASSERT(expr) MPFR_ASSERTD(expr)
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 EXP(x) ((x)->_mp_exp)
167 #define PREC(x) ((x)->_mp_prec)
168 #define ALLOC(x) ((x)->_mp_alloc)
169 #define MPZ_REALLOC(z,n) ((n) > ALLOC(z) ? _mpz_realloc(z,n) : PTR(z))
171 /* Non IEEE float supports -- needs to detect them with proper configure */
172 #undef XDEBUG
173 #define XDEBUG
175 /* For longlong.h */
176 #ifdef HAVE_ATTRIBUTE_MODE
177 typedef unsigned int UQItype __attribute__ ((mode (QI)));
178 typedef int SItype __attribute__ ((mode (SI)));
179 typedef unsigned int USItype __attribute__ ((mode (SI)));
180 typedef int DItype __attribute__ ((mode (DI)));
181 typedef unsigned int UDItype __attribute__ ((mode (DI)));
182 #else
183 typedef unsigned char UQItype;
184 typedef long SItype;
185 typedef unsigned long USItype;
186 #ifdef HAVE_LONG_LONG
187 typedef long long int DItype;
188 typedef unsigned long long int UDItype;
189 #else /* Assume `long' gives us a wide enough type. Needed for hppa2.0w. */
190 typedef long int DItype;
191 typedef unsigned long int UDItype;
192 #endif
193 #endif
194 typedef mp_limb_t UWtype;
195 typedef unsigned int UHWtype;
196 #define W_TYPE_SIZE GMP_NUMB_BITS
198 /* Remap names of internal mpn functions (for longlong.h). */
199 #undef __clz_tab
200 #define __clz_tab mpfr_clz_tab
202 /* Use (4.0 * ...) instead of (2.0 * ...) to work around buggy compilers
203 that don't convert ulong->double correctly (eg. SunOS 4 native cc). */
204 #undef MP_BASE_AS_DOUBLE
205 #define MP_BASE_AS_DOUBLE (4.0 * ((mp_limb_t) 1 << (GMP_NUMB_BITS - 2)))
207 /* Structure for conversion between internal binary format and
208 strings in base 2..36. */
209 struct bases
211 /* log(2)/log(conversion_base) */
212 double chars_per_bit_exactly;
214 #undef __mp_bases
215 #define __mp_bases mpfr_bases
216 __MPFR_DECLSPEC extern const struct bases mpfr_bases[257];
218 /* Standard macros */
219 #undef ABS
220 #undef MIN
221 #undef MAX
222 #undef numberof
223 #define ABS(x) ((x) >= 0 ? (x) : -(x))
224 #define MIN(l,o) ((l) < (o) ? (l) : (o))
225 #define MAX(h,i) ((h) > (i) ? (h) : (i))
226 #define numberof(x) (sizeof (x) / sizeof ((x)[0]))
228 /* Random */
229 #undef __gmp_rands_initialized
230 #undef __gmp_rands
231 #define __gmp_rands_initialized mpfr_rands_initialized
232 #define __gmp_rands mpfr_rands
234 __MPFR_DECLSPEC extern char mpfr_rands_initialized;
235 __MPFR_DECLSPEC extern gmp_randstate_t mpfr_rands;
237 #undef RANDS
238 #define RANDS \
239 ((__gmp_rands_initialized ? 0 \
240 : (__gmp_rands_initialized = 1, \
241 gmp_randinit_default (__gmp_rands), 0)), \
242 __gmp_rands)
244 #undef RANDS_CLEAR
245 #define RANDS_CLEAR() \
246 do { \
247 if (__gmp_rands_initialized) \
249 __gmp_rands_initialized = 0; \
250 gmp_randclear (__gmp_rands); \
252 } while (0)
254 typedef __gmp_randstate_struct *gmp_randstate_ptr;
256 /* Allocate func are defined in gmp-impl.h */
258 /* In newer GMP, there aren't anymore __gmp_allocate_func,
259 __gmp_reallocate_func & __gmp_free_func in gmp.h
260 Just getting the correct value by calling mp_get_memory_functions */
261 #ifdef mp_get_memory_functions
263 #undef __gmp_allocate_func
264 #undef __gmp_reallocate_func
265 #undef __gmp_free_func
266 #define MPFR_GET_MEMFUNC mp_get_memory_functions(&mpfr_allocate_func, &mpfr_reallocate_func, &mpfr_free_func)
267 #define __gmp_allocate_func (MPFR_GET_MEMFUNC, mpfr_allocate_func)
268 #define __gmp_reallocate_func (MPFR_GET_MEMFUNC, mpfr_reallocate_func)
269 #define __gmp_free_func (MPFR_GET_MEMFUNC, mpfr_free_func)
270 __MPFR_DECLSPEC extern void * (*mpfr_allocate_func) _MPFR_PROTO ((size_t));
271 __MPFR_DECLSPEC extern void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *,
272 size_t, size_t));
273 __MPFR_DECLSPEC extern void (*mpfr_free_func) _MPFR_PROTO ((void *,
274 size_t));
276 #endif
278 #undef __gmp_default_allocate
279 #undef __gmp_default_reallocate
280 #undef __gmp_default_free
281 #define __gmp_default_allocate mpfr_default_allocate
282 #define __gmp_default_reallocate mpfr_default_reallocate
283 #define __gmp_default_free mpfr_default_free
284 __MPFR_DECLSPEC void *__gmp_default_allocate _MPFR_PROTO ((size_t));
285 __MPFR_DECLSPEC void *__gmp_default_reallocate _MPFR_PROTO ((void *, size_t,
286 size_t));
287 __MPFR_DECLSPEC void __gmp_default_free _MPFR_PROTO ((void *, size_t));
289 #if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
290 #ifndef __gmpn_rootrem
291 __MPFR_DECLSPEC mp_size_t __gmpn_rootrem _MPFR_PROTO ((mp_limb_t*,
292 mp_limb_t*, mp_limb_t*, mp_size_t, mp_limb_t));
293 #endif
294 #endif
296 #if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
297 #ifndef __gmpn_sbpi1_divappr_q
298 __MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q _MPFR_PROTO ((mp_limb_t*,
299 mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t));
300 #endif
301 #endif
303 /* Temp memory allocate */
305 struct tmp_marker
307 void *ptr;
308 size_t size;
309 struct tmp_marker *next;
312 __MPFR_DECLSPEC void *mpfr_tmp_allocate _MPFR_PROTO ((struct tmp_marker **,
313 size_t));
314 __MPFR_DECLSPEC void mpfr_tmp_free _MPFR_PROTO ((struct tmp_marker *));
316 /* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */
317 #define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ? \
318 alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n)))
319 #define TMP_DECL(m) struct tmp_marker *tmp_marker
320 #define TMP_MARK(m) (tmp_marker = 0)
321 #define TMP_FREE(m) mpfr_tmp_free (tmp_marker)
323 /* invert_limb macro, copied from GMP 5.0.2, file gmp-impl.h.
324 It returns invxl = floor((B^2-1)/xl)-B, where B=2^BITS_PER_LIMB,
325 assuming the most significant bit of xl is set. */
326 #undef invert_limb
327 #define invert_limb(invxl,xl) \
328 do { \
329 mp_limb_t dummy; \
330 MPFR_ASSERTD ((xl) != 0); \
331 udiv_qrnnd (invxl, dummy, ~(xl), ~(mp_limb_t)0, xl); \
332 } while (0)
334 typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
335 mpfr_pi1_t to avoid using
336 GMP's namespace. */
337 /* invert_pi1 macro, adapted from GMP 5.0.2, file gmp-impl.h.
338 It returns dinv = floor((B^3-1)/(d1*B+d0))-B, where B=2^BITS_PER_LIMB,
339 assuming the most significant bit of d1 is set. */
340 #undef invert_pi1
341 #define invert_pi1(dinv, d1, d0) \
342 do { \
343 mp_limb_t _v, _p, _t1, _t0, _mask; \
344 invert_limb (_v, d1); \
345 _p = d1 * _v; \
346 _p += d0; \
347 if (_p < d0) \
349 _v--; \
350 _mask = -(_p >= d1); \
351 _p -= d1; \
352 _v += _mask; \
353 _p -= _mask & d1; \
355 umul_ppmm (_t1, _t0, d0, _v); \
356 _p += _t1; \
357 if (_p < _t1) \
359 _v--; \
360 if (MPFR_UNLIKELY (_p >= d1)) \
362 if (_p > d1 || _t0 >= d0) \
363 _v--; \
366 (dinv).inv32 = _v; \
367 } while (0)
369 /* udiv_qr_3by2 macro, adapted from GMP 5.0.2, file gmp-impl.h.
370 Compute quotient the quotient and remainder for n / d. Requires d
371 >= B^2 / 2 and n < d B. dinv is the inverse
373 floor ((B^3 - 1) / (d0 + d1 B)) - B.
375 NOTE: Output variables are updated multiple times. Only some inputs
376 and outputs may overlap.
378 #undef udiv_qr_3by2
379 #define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
380 do { \
381 mp_limb_t _q0, _t1, _t0, _mask; \
382 umul_ppmm ((q), _q0, (n2), (dinv)); \
383 add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
385 /* Compute the two most significant limbs of n - q'd */ \
386 (r1) = (n1) - (d1) * (q); \
387 (r0) = (n0); \
388 sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
389 umul_ppmm (_t1, _t0, (d0), (q)); \
390 sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
391 (q)++; \
393 /* Conditionally adjust q and the remainders */ \
394 _mask = - (mp_limb_t) ((r1) >= _q0); \
395 (q) += _mask; \
396 add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
397 if (MPFR_UNLIKELY ((r1) >= (d1))) \
399 if ((r1) > (d1) || (r0) >= (d0)) \
401 (q)++; \
402 sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
405 } while (0)
407 #if defined (__cplusplus)
409 #endif
411 #endif /* Gmp internal emulator */