Import mpfr-2.4.1
[dragonfly.git] / contrib / mpfr / mpfr-gmp.h
1 /* Interface to replace gmp-impl.h
2
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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 2.1 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.LIB.  If not, write to
20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 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 #ifndef alloca
36 # if defined ( __GNUC__ )
37 #  define alloca __builtin_alloca
38 # elif defined (__DECC)
39 #  define alloca(x) __ALLOCA(x)
40 # elif defined (_MSC_VER)
41 #  include <malloc.h>
42 #  define alloca _alloca
43 # elif defined (HAVE_ALLOCA_H)
44 #  include <alloca.h>
45 # elif defined (_AIX) || defined (_IBMR2)
46 #  pragma alloca
47 # else
48 char *alloca ();
49 # endif
50 #endif
51
52 #if defined (__cplusplus)
53 extern "C" {
54 #endif
55
56 /* Define BITS_PER_MP_LIMB
57    Can't use sizeof(mp_limb_t) since it should be a preprocessor constant */
58 #if defined(GMP_NUMB_BITS) /* GMP 4.1.2 or above */
59 # define BITS_PER_MP_LIMB  (GMP_NUMB_BITS+GMP_NAIL_BITS)
60 #elif defined (__GMP_BITS_PER_MP_LIMB) /* Older versions 4.x.x */
61 # define BITS_PER_MP_LIMB  __GMP_BITS_PER_MP_LIMB
62 # define GMP_NUMB_BITS BITS_PER_MP_LIMB
63 # ifndef GMP_NAIL_BITS
64 #  define GMP_NAIL_BITS 0
65 # endif
66 #else
67 # error "Could not detect BITS_PER_MP_LIMB. Try with gmp internal files."
68 #endif
69
70 /* Define some macros */
71 #define BYTES_PER_MP_LIMB (BITS_PER_MP_LIMB/CHAR_BIT)
72
73 #define MP_LIMB_T_MAX (~(mp_limb_t)0)
74
75 #define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1))
76 #define UINT_HIGHBIT  (UINT_MAX ^ ((unsigned) UINT_MAX >> 1))
77 #define USHRT_HIGHBIT ((unsigned short) (USHRT_MAX ^ ((unsigned short) USHRT_MAX >> 1)))
78
79 #define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
80
81
82 #if __GMP_MP_SIZE_T_INT
83 #define MP_SIZE_T_MAX      INT_MAX
84 #define MP_SIZE_T_MIN      INT_MIN
85 #else
86 #define MP_SIZE_T_MAX      LONG_MAX
87 #define MP_SIZE_T_MIN      LONG_MIN
88 #endif
89
90 #define LONG_HIGHBIT       LONG_MIN
91 #define INT_HIGHBIT        INT_MIN
92 #define SHRT_HIGHBIT       SHRT_MIN
93
94 /* MP_LIMB macros */
95 #define MPN_ZERO(dst, n) memset((dst), 0, (n)*BYTES_PER_MP_LIMB)
96 #define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
97 #define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
98 #define MPN_COPY(dst,src,n) \
99   do                                                                  \
100     {                                                                 \
101       if ((dst) != (src))                                             \
102         {                                                             \
103           MPFR_ASSERTD ((char *) (dst) >= (char *) (src) +            \
104                                           (n) * BYTES_PER_MP_LIMB ||  \
105                         (char *) (src) >= (char *) (dst) +            \
106                                           (n) * BYTES_PER_MP_LIMB);   \
107           memcpy ((dst), (src), (n) * BYTES_PER_MP_LIMB);             \
108         }                                                             \
109     }                                                                 \
110   while (0)
111
112 /* MPN macros taken from gmp-impl.h */
113 #define MPN_NORMALIZE(DST, NLIMBS) \
114   do {                                        \
115     while (NLIMBS > 0)                        \
116       {                                       \
117         if ((DST)[(NLIMBS) - 1] != 0)         \
118           break;                              \
119         NLIMBS--;                             \
120       }                                       \
121   } while (0)
122 #define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS)     \
123   do {                                          \
124     MPFR_ASSERTD ((NLIMBS) >= 1);               \
125     while (1)                                   \
126       {                                         \
127         if ((DST)[(NLIMBS) - 1] != 0)           \
128           break;                                \
129         NLIMBS--;                               \
130       }                                         \
131   } while (0)
132 #define MPN_OVERLAP_P(xp, xsize, yp, ysize) \
133   ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp))
134 #define MPN_SAME_OR_INCR2_P(dst, dsize, src, ssize)             \
135   ((dst) <= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
136 #define MPN_SAME_OR_INCR_P(dst, src, size)      \
137   MPN_SAME_OR_INCR2_P(dst, size, src, size)
138 #define MPN_SAME_OR_DECR2_P(dst, dsize, src, ssize)             \
139   ((dst) >= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
140 #define MPN_SAME_OR_DECR_P(dst, src, size)      \
141   MPN_SAME_OR_DECR2_P(dst, size, src, size)
142
143 /* If sqr_n or mul_basecase are not exported, used mpn_mul instead */
144 #ifndef mpn_sqr_n
145 # define mpn_sqr_n(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
146 #endif
147 #ifndef mpn_mul_basecase
148 # define mpn_mul_basecase(dst,s1,n1,s2,n2) mpn_mul((dst),(s1),(n1),(s2),(n2))
149 #endif
150 #ifndef mpn_sqr_basecase
151 # define mpn_sqr_basecase(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
152 #endif
153
154 /* ASSERT */
155 __MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int,
156                                                    const char *));
157
158 #define ASSERT_FAIL(expr)  mpfr_assert_fail (__FILE__, __LINE__, #expr)
159 #define ASSERT(expr)       MPFR_ASSERTD(expr)
160
161 /* Access fileds of GMP struct */
162 #define SIZ(x) ((x)->_mp_size)
163 #define ABSIZ(x) ABS (SIZ (x))
164 #define PTR(x) ((x)->_mp_d)
165 #define LIMBS(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))
170
171 /* Non IEEE float supports -- needs to detect them with proper configure */
172 #undef  XDEBUG
173 #define XDEBUG
174
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 BITS_PER_MP_LIMB
197
198 /* Remap names of internal mpn functions (for longlong.h).  */
199 #undef  __clz_tab
200 #define __clz_tab               mpfr_clz_tab
201
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)))
206
207 /* Structure for conversion between internal binary format and
208    strings in base 2..36.  */
209 struct bases
210 {
211   /* log(2)/log(conversion_base) */
212   double chars_per_bit_exactly;
213 };
214 #undef  __mp_bases
215 #define __mp_bases mpfr_bases
216 __MPFR_DECLSPEC extern const struct bases mpfr_bases[257];
217
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]))
227
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
233
234 __MPFR_DECLSPEC extern char             mpfr_rands_initialized;
235 __MPFR_DECLSPEC extern gmp_randstate_t  mpfr_rands;
236
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)
243
244 #undef RANDS_CLEAR
245 #define RANDS_CLEAR()                   \
246   do {                                  \
247     if (__gmp_rands_initialized)        \
248       {                                 \
249         __gmp_rands_initialized = 0;    \
250         gmp_randclear (__gmp_rands);    \
251       }                                 \
252   } while (0)
253
254 typedef __gmp_randstate_struct *gmp_randstate_ptr;
255
256 #undef _gmp_rand
257 #define _gmp_rand mpfr_rand_raw
258 __MPFR_DECLSPEC void mpfr_rand_raw _MPFR_PROTO((mp_ptr, gmp_randstate_t,
259                                                 unsigned long));
260
261 /* Allocate func are defined in gmp-impl.h */
262
263 /* In newer GMP, there aren't anymore __gmp_allocate_func,
264    __gmp_reallocate_func & __gmp_free_func in gmp.h
265    Just getting the correct value by calling mp_get_memory_functions */
266 #ifdef mp_get_memory_functions
267
268 #undef __gmp_allocate_func
269 #undef __gmp_reallocate_func
270 #undef __gmp_free_func
271 #define MPFR_GET_MEMFUNC mp_get_memory_functions(&mpfr_allocate_func, &mpfr_reallocate_func, &mpfr_free_func)
272 #define __gmp_allocate_func   (MPFR_GET_MEMFUNC, mpfr_allocate_func)
273 #define __gmp_reallocate_func (MPFR_GET_MEMFUNC, mpfr_reallocate_func)
274 #define __gmp_free_func       (MPFR_GET_MEMFUNC, mpfr_free_func)
275 __MPFR_DECLSPEC extern void * (*mpfr_allocate_func)   _MPFR_PROTO ((size_t));
276 __MPFR_DECLSPEC extern void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *,
277                                                           size_t, size_t));
278 __MPFR_DECLSPEC extern void   (*mpfr_free_func)       _MPFR_PROTO ((void *,
279                                                                     size_t));
280
281 #endif
282
283 #undef __gmp_default_allocate
284 #undef __gmp_default_reallocate
285 #undef __gmp_default_free
286 #define __gmp_default_allocate   mpfr_default_allocate
287 #define __gmp_default_reallocate mpfr_default_reallocate
288 #define __gmp_default_free       mpfr_default_free
289 __MPFR_DECLSPEC void *__gmp_default_allocate _MPFR_PROTO ((size_t));
290 __MPFR_DECLSPEC void *__gmp_default_reallocate _MPFR_PROTO ((void *, size_t,
291                                                              size_t));
292 __MPFR_DECLSPEC void __gmp_default_free _MPFR_PROTO ((void *, size_t));
293
294 /* Temp memory allocate */
295
296 struct tmp_marker
297 {
298   void *ptr;
299   size_t size;
300   struct tmp_marker *next;
301 };
302
303 __MPFR_DECLSPEC void *mpfr_tmp_allocate _MPFR_PROTO ((struct tmp_marker **,
304                                                       size_t));
305 __MPFR_DECLSPEC void mpfr_tmp_free _MPFR_PROTO ((struct tmp_marker *));
306
307 /* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */
308 #define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ?       \
309                       alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n)))
310 #define TMP_DECL(m) struct tmp_marker *tmp_marker
311 #define TMP_MARK(m) (tmp_marker = 0)
312 #define TMP_FREE(m) mpfr_tmp_free (tmp_marker)
313
314 #if defined (__cplusplus)
315 }
316 #endif
317
318 #endif /* Gmp internal emulator */