1 /* gmp.h -- Definitions for GNU multiple precision functions.
2
3 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000 Free Software
4 Foundation, Inc.
5
6 This file is part of the GNU MP Library.
7
8 The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, USA. */
22
23 #ifndef __GMP_H__
24
25 #ifndef __GNU_MP__ /* to allow inclusion of both gmp.h and mp.h */
26 #define __GNU_MP__ 2
27 #define __need_size_t
28 #include <stddef.h>
29 #undef __need_size_t
30
31 #if defined(_MSC_VER)
32 # ifndef __STDC__
33 # define __STDC__ 1
34 # endif
35 #endif
36
37 #if defined(__BORLANDC__)
38 # ifndef __STDC__
39 # define __STDC__ 1
40 # endif
41 #endif
42
43 #if 0
44 # if (defined (__mips) || defined(mips)) && defined (_ABIN32)
45 /* Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI permits. */
46 # define _LONG_LONG_LIMB
47 # endif
48 #endif
49
50 #ifdef USE_LONG_LONG_FOR_BIGDIG
51 # define _LONG_LONG_LIMB
52 #endif
53
54 #if (__STDC__-0) || defined (__cplusplus)
55 #define __gmp_const const
56 #define __gmp_signed signed
57 #else
58 #define __gmp_const
59 #define __gmp_signed
60 #endif
61
62 #if defined (__GNUC__)
63 #define __gmp_inline __inline__
64 #else
65 #define __gmp_inline
66 #endif
67
68 #ifndef _EXTERN_INLINE
69 /* __GNUC__ case disabled to avoid unnecessary compiler dependencies */
70 #if defined(__GNUC__) && 0
71 #define _EXTERN_INLINE extern __inline__
72 #else
73 #define _EXTERN_INLINE static __gmp_inline
74 #endif
75 #endif
76
77 /* To avoid unnecessary compiler dependencies, always defined: */
78 #define _FORCE_INLINES
79
80 #ifdef _SHORT_LIMB
81 typedef unsigned int mp_limb_t;
82 typedef int mp_limb_signed_t;
83 #else
84 #ifdef _LONG_LONG_LIMB
85 typedef unsigned long long int mp_limb_t;
86 typedef long long int mp_limb_signed_t;
87 #else
88 typedef uintptr_t mp_limb_t;
89 typedef intptr_t mp_limb_signed_t;
90 #endif
91 #endif
92
93 typedef mp_limb_t * mp_ptr;
94 typedef __gmp_const mp_limb_t * mp_srcptr;
95 #if defined (_CRAY) && ! defined (_CRAYMPP)
96 /* plain `int' is much faster (48 bits) */
97 typedef int mp_size_t;
98 typedef int mp_exp_t;
99 #else
100 typedef intptr_t mp_size_t;
101 typedef intptr_t mp_exp_t;
102 #endif
103
104 typedef struct
105 {
106 int _mp_alloc; /* Number of *limbs* allocated and pointed
107 to by the _mp_d field. */
108 int _mp_size; /* abs(_mp_size) is the number of limbs the
109 last field points to. If _mp_size is
110 negative this is a negative number. */
111 mp_limb_t *_mp_d; /* Pointer to the limbs. */
112 } __mpz_struct;
113 #endif /* __GNU_MP__ */
114
115 typedef __mpz_struct MP_INT;
116 typedef __mpz_struct mpz_t[1];
117
118 typedef struct
119 {
120 __mpz_struct _mp_num;
121 __mpz_struct _mp_den;
122 } __mpq_struct;
123
124 typedef __mpq_struct MP_RAT;
125 typedef __mpq_struct mpq_t[1];
126
127 typedef struct
128 {
129 int _mp_prec; /* Max precision, in number of `mp_limb_t's.
130 Set by mpf_init and modified by
131 mpf_set_prec. The area pointed to by the
132 _mp_d field contains `prec' + 1 limbs. */
133 int _mp_size; /* abs(_mp_size) is the number of limbs the
134 last field points to. If _mp_size is
135 negative this is a negative number. */
136 mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */
137 mp_limb_t *_mp_d; /* Pointer to the limbs. */
138 } __mpf_struct;
139
140 /* typedef __mpf_struct MP_FLOAT; */
141 typedef __mpf_struct mpf_t[1];
142
143 /* Available random number generation algorithms. */
144 typedef enum
145 {
146 GMP_RAND_ALG_DEFAULT = 0,
147 GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential. */
148 } gmp_randalg_t;
149
150 /* Linear congruential data struct. */
151 typedef struct {
152 mpz_t a; /* Multiplier. */
153 unsigned long int c; /* Adder. */
154 mpz_t m; /* Modulus (valid only if m2exp == 0). */
155 unsigned long int m2exp; /* If != 0, modulus is 2 ^ m2exp. */
156 } __gmp_randata_lc;
157
158 /* Random state struct. */
159 typedef struct
160 {
161 mpz_t seed; /* Current seed. */
162 gmp_randalg_t alg; /* Algorithm used. */
163 union { /* Algorithm specific data. */
164 __gmp_randata_lc *lc; /* Linear congruential. */
165 } algdata;
166 } __gmp_randstate_struct;
167 typedef __gmp_randstate_struct gmp_randstate_t[1];
168
169 /* Types for function declarations in gmp files. */
170 /* ??? Should not pollute user name space with these ??? */
171 typedef __gmp_const __mpz_struct *mpz_srcptr;
172 typedef __mpz_struct *mpz_ptr;
173 typedef __gmp_const __mpf_struct *mpf_srcptr;
174 typedef __mpf_struct *mpf_ptr;
175 typedef __gmp_const __mpq_struct *mpq_srcptr;
176 typedef __mpq_struct *mpq_ptr;
177
178 #ifndef _PROTO
179 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
180 #define _PROTO(x) x
181 #else
182 #define _PROTO(x) ()
183 #endif
184 #endif
185
186 #ifndef __MPN
187 /* Really use `defined (__STDC__)' here; we want it to be true for Sun C */
188 #if defined (__STDC__) || defined (__cplusplus) || defined(__BORLANDC__)
189 #define __MPN(x) scheme_gmpn_##x
190 #else
191 #define __MPN(x) scheme_gmpn_/**/x
192 #endif
193 #endif
194
195 #if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \
196 || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \
197 || defined (_STDIO_INCLUDED) || defined (__dj_include_stdio_h_)
198 #define _GMP_H_HAVE_FILE 1
199 #endif
200
201 #if defined (__cplusplus)
202 extern "C" {
203 #endif
204
205 #define mp_set_memory_functions __gmp_set_memory_functions
206 void mp_set_memory_functions _PROTO ((void *(*) (size_t),
207 void *(*) (void *, size_t, size_t),
208 void (*) (void *, size_t)));
209
210 #define mp_bits_per_limb __gmp_bits_per_limb
211 extern __gmp_const int mp_bits_per_limb;
212
213 #if defined (__cplusplus)
214 }
215 #endif
216
217
218 /************ Low level positive-integer (i.e. N) routines. ************/
219
220 /* This is ugly, but we need to make user calls reach the prefixed function. */
221 #define mpn_add __MPN(add)
222 #define mpn_add_1 __MPN(add_1)
223 #define mpn_add_n __MPN(add_n)
224 #define mpn_add_nc __MPN(add_nc)
225 #define mpn_addmul_1 __MPN(addmul_1)
226 #define mpn_addsub_n __MPN(addsub_n)
227 #define mpn_addsub_nc __MPN(addsub_nc)
228 /* #define mpn_and_n __MPN(and_n) */
229 /* #define mpn_andn_n __MPN(andn_n) */
230 #define mpn_bdivmod __MPN(bdivmod)
231 #define mpn_cmp __MPN(cmp)
232 /* #define mpn_com_n __MPN(com_n) */
233 #define mpn_copyd __MPN(copyd)
234 #define mpn_copyi __MPN(copyi)
235 #define mpn_divrem __MPN(divrem)
236 #define mpn_divrem_1 __MPN(divrem_1)
237 #define mpn_divrem_2 __MPN(divrem_2)
238 #define mpn_dump __MPN(dump)
239 #define mpn_gcd __MPN(gcd)
240 #define mpn_gcd_1 __MPN(gcd_1)
241 #define mpn_gcdext __MPN(gcdext)
242 #define mpn_get_str __MPN(get_str)
243 #define mpn_hamdist __MPN(hamdist)
244 #define mpn_invert_limb __MPN(invert_limb)
245 /* #define mpn_ior_n __MPN(ior_n) */
246 /* #define mpn_iorn_n __MPN(iorn_n) */
247 /* #define mpn_kara_mul_n __MPN(kara_mul_n) internal */
248 /* #define mpn_kara_sqr_n __MPN(kara_sqr_n) internal */
249 #define mpn_lshift __MPN(lshift)
250 #define mpn_lshiftc __MPN(lshiftc)
251 #define mpn_mod_1 __MPN(mod_1)
252 #define mpn_mul __MPN(mul)
253 #define mpn_mul_1 __MPN(mul_1)
254 #define mpn_mul_basecase __MPN(mul_basecase)
255 #define mpn_mul_n __MPN(mul_n)
256 #define mpn_perfect_square_p __MPN(perfect_square_p)
257 #define mpn_popcount __MPN(popcount)
258 #define mpn_preinv_mod_1 __MPN(preinv_mod_1)
259 /* #define mpn_nand_n __MPN(nand_n) */
260 /* #define mpn_nior_n __MPN(nior_n) */
261 #define mpn_random __MPN(random)
262 #define mpn_random2 __MPN(random2)
263 #define mpn_rshift __MPN(rshift)
264 #define mpn_rshiftc __MPN(rshiftc)
265 #define mpn_scan0 __MPN(scan0)
266 #define mpn_scan1 __MPN(scan1)
267 #define mpn_set_str __MPN(set_str)
268 #define mpn_sqr_basecase __MPN(sqr_basecase)
269 #define mpn_sqr_n __MPN(sqr_n)
270 #define mpn_sqrtrem __MPN(sqrtrem)
271 #define mpn_sub __MPN(sub)
272 #define mpn_sub_1 __MPN(sub_1)
273 #define mpn_sub_n __MPN(sub_n)
274 #define mpn_sub_nc __MPN(sub_nc)
275 #define mpn_submul_1 __MPN(submul_1)
276 /* #define mpn_toom3_mul_n __MPN(toom3_mul_n) internal */
277 /* #define mpn_toom3_sqr_n __MPN(toom3_sqr_n) internal */
278 /* #define mpn_xnor_n __MPN(xnor_n) */
279 /* #define mpn_xor_n __MPN(xor_n) */
280
281 #ifdef MZ_PRECISE_GC
282 # define XFORM_GMP_NONGCING XFORM_NONGCING
283 #else
284 # define XFORM_GMP_NONGCING /**/
285 #endif
286
287 #if defined (__cplusplus)
288 extern "C" {
289 #endif
290 _EXTERN_INLINE mp_limb_t mpn_add _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
291 _EXTERN_INLINE mp_limb_t mpn_add_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
292 mp_limb_t mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
293 mp_limb_t mpn_add_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t));
294
295 mp_limb_t mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
296
297 #define mpn_addmul_1c __MPN(addmul_1c)
298 mp_limb_t mpn_addmul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
299
300 mp_limb_t mpn_addsub_n _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
301 mp_limb_t mpn_bdivmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, unsigned long int));
302 XFORM_GMP_NONGCING int mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
303
304 #define mpn_divexact_by3(dst, src, size) mpn_divexact_by3c (dst, src, size, 0)
305
306 #define mpn_divexact_by3c __MPN(divexact_by3c)
307 mp_limb_t mpn_divexact_by3c _PROTO ((mp_ptr dst, mp_srcptr src,
308 mp_size_t size, mp_limb_t carry));
309
310 #define mpn_divmod_1(qp,np,nsize,dlimb) mpn_divrem_1 (qp,0,np,nsize,dlimb)
311
312 mp_limb_t mpn_divrem _PROTO((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t));
313
314 mp_limb_t mpn_divrem_1 _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t));
315
316 #define mpn_divrem_1c __MPN(divrem_1c)
317 mp_limb_t mpn_divrem_1c _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t,
318 mp_limb_t, mp_limb_t));
319
320 mp_limb_t mpn_divrem_2 _PROTO ((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr));
321 void mpn_dump _PROTO ((mp_srcptr, mp_size_t));
322 mp_size_t mpn_gcd _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
323 mp_limb_t mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
324 mp_size_t mpn_gcdext _PROTO ((mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
325 size_t mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t));
326 unsigned long int mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
327
328 #define mpn_jacobi_base __MPN(jacobi_base)
329 int mpn_jacobi_base _PROTO ((mp_limb_t a, mp_limb_t b, int result_bit1));
330
331 mp_limb_t mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
332 mp_limb_t mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
333
334 #define mpn_mod_1c __MPN(mod_1c)
335 mp_limb_t mpn_mod_1c _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
336
337 #define mpn_mod_1_rshift __MPN(mod_1_rshift)
338 mp_limb_t mpn_mod_1_rshift _PROTO ((mp_srcptr, mp_size_t, unsigned,mp_limb_t));
339
340 mp_limb_t mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
341 mp_limb_t mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
342
343 #define mpn_mul_1c __MPN(mul_1c)
344 mp_limb_t mpn_mul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
345
346 void mpn_mul_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
347 void mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
348 int mpn_perfect_square_p _PROTO ((mp_srcptr, mp_size_t));
349 unsigned long int mpn_popcount _PROTO ((mp_srcptr, mp_size_t));
350 mp_limb_t mpn_preinv_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
351 void mpn_random _PROTO ((mp_ptr, mp_size_t));
352 void mpn_random2 _PROTO ((mp_ptr, mp_size_t));
353 mp_limb_t mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
354 unsigned long int mpn_scan0 _PROTO ((mp_srcptr, unsigned long int));
355 unsigned long int mpn_scan1 _PROTO ((mp_srcptr, unsigned long int));
356 mp_size_t mpn_set_str _PROTO ((mp_ptr, __gmp_const unsigned char *, size_t, int));
357 void mpn_sqr_n _PROTO ((mp_ptr, mp_srcptr, mp_size_t));
358 void mpn_sqr_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t));
359 mp_size_t mpn_sqrtrem _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t));
360 _EXTERN_INLINE mp_limb_t mpn_sub _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
361 _EXTERN_INLINE mp_limb_t mpn_sub_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
362 mp_limb_t mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
363 mp_limb_t mpn_sub_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t));
364 mp_limb_t mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
365
366 #define mpn_submul_1c __MPN(submul_1c)
367 mp_limb_t mpn_submul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
368
369 #define mpn_tdiv_qr __MPN(tdiv_qr)
370 void mpn_tdiv_qr _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
371
372 #if defined (__cplusplus)
373 }
374 #endif
375
376 #define mpn_incr_u(p,incr) \
377 do { mp_limb_t __x; mp_ptr __p = p; \
378 __x = *__p + incr; \
379 *__p = __x; \
380 if (__x < incr) \
381 while (++(*(++__p)) == 0) {} \
382 } while (0)
383
384 #define mpn_decr_u(p,incr) \
385 do { mp_limb_t __x; mp_ptr __p = p; \
386 __x = *__p; \
387 *__p = __x - incr; \
388 if (__x < incr) \
389 while ((*(++__p))-- == 0) {} \
390 } while (0)
391
392 #if (defined (__GNUC__) || defined (_FORCE_INLINES)) && !defined(PALMOS_STUFF)
393 _EXTERN_INLINE mp_limb_t
394 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
mpn_add_1(register mp_ptr res_ptr,register mp_srcptr s1_ptr,register mp_size_t s1_size,register mp_limb_t s2_limb)395 mpn_add_1 (register mp_ptr res_ptr,
396 register mp_srcptr s1_ptr,
397 register mp_size_t s1_size,
398 register mp_limb_t s2_limb)
399 #else
400 mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb)
401 register mp_ptr res_ptr;
402 register mp_srcptr s1_ptr;
403 register mp_size_t s1_size;
404 register mp_limb_t s2_limb;
405 #endif
406 {
407 register mp_limb_t x;
408
409 x = *s1_ptr++;
410 s2_limb = x + s2_limb;
411 *res_ptr++ = s2_limb;
412 if (s2_limb < x)
413 {
414 while (--s1_size != 0)
415 {
416 x = *s1_ptr++ + 1;
417 *res_ptr++ = x;
418 if (x != 0)
419 goto fin;
420 }
421
422 return 1;
423 }
424
425 fin:
426 if (res_ptr != s1_ptr)
427 {
428 mp_size_t i;
429 for (i = 0; i < s1_size - 1; i++) {
430 res_ptr[i] = s1_ptr[i];
431 }
432 }
433 return 0;
434 }
435
436 _EXTERN_INLINE mp_limb_t
437 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
mpn_add(register mp_ptr res_ptr,register mp_srcptr s1_ptr,register mp_size_t s1_size,register mp_srcptr s2_ptr,register mp_size_t s2_size)438 mpn_add (register mp_ptr res_ptr,
439 register mp_srcptr s1_ptr,
440 register mp_size_t s1_size,
441 register mp_srcptr s2_ptr,
442 register mp_size_t s2_size)
443 #else
444 mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
445 register mp_ptr res_ptr;
446 register mp_srcptr s1_ptr;
447 register mp_size_t s1_size;
448 register mp_srcptr s2_ptr;
449 register mp_size_t s2_size;
450 #endif
451 {
452 mp_limb_t cy_limb = 0;
453
454 if (s2_size != 0)
455 cy_limb = mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size);
456
457 if (s1_size - s2_size != 0)
458 cy_limb = mpn_add_1 (res_ptr + s2_size,
459 s1_ptr + s2_size,
460 s1_size - s2_size,
461 cy_limb);
462 return cy_limb;
463 }
464
465 _EXTERN_INLINE mp_limb_t
466 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
mpn_sub_1(register mp_ptr res_ptr,register mp_srcptr s1_ptr,register mp_size_t s1_size,register mp_limb_t s2_limb)467 mpn_sub_1 (register mp_ptr res_ptr,
468 register mp_srcptr s1_ptr,
469 register mp_size_t s1_size,
470 register mp_limb_t s2_limb)
471 #else
472 mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb)
473 register mp_ptr res_ptr;
474 register mp_srcptr s1_ptr;
475 register mp_size_t s1_size;
476 register mp_limb_t s2_limb;
477 #endif
478 {
479 register mp_limb_t x;
480
481 x = *s1_ptr++;
482 s2_limb = x - s2_limb;
483 *res_ptr++ = s2_limb;
484 if (s2_limb > x)
485 {
486 while (--s1_size != 0)
487 {
488 x = *s1_ptr++;
489 *res_ptr++ = x - 1;
490 if (x != 0)
491 goto fin;
492 }
493
494 return 1;
495 }
496
497 fin:
498 if (res_ptr != s1_ptr)
499 {
500 mp_size_t i;
501 for (i = 0; i < s1_size - 1; i++) {
502 res_ptr[i] = s1_ptr[i];
503 }
504 }
505 return 0;
506 }
507
508 _EXTERN_INLINE mp_limb_t
509 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
mpn_sub(register mp_ptr res_ptr,register mp_srcptr s1_ptr,register mp_size_t s1_size,register mp_srcptr s2_ptr,register mp_size_t s2_size)510 mpn_sub (register mp_ptr res_ptr,
511 register mp_srcptr s1_ptr,
512 register mp_size_t s1_size,
513 register mp_srcptr s2_ptr,
514 register mp_size_t s2_size)
515 #else
516 mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
517 register mp_ptr res_ptr;
518 register mp_srcptr s1_ptr;
519 register mp_size_t s1_size;
520 register mp_srcptr s2_ptr;
521 register mp_size_t s2_size;
522 #endif
523 {
524 mp_limb_t cy_limb = 0;
525
526 if (s2_size != 0)
527 cy_limb = mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size);
528
529 if (s1_size - s2_size != 0)
530 cy_limb = mpn_sub_1 (res_ptr + s2_size,
531 s1_ptr + s2_size,
532 s1_size - s2_size,
533 cy_limb);
534 return cy_limb;
535 }
536 #endif /* __GNUC__ */
537
538 /* Allow faster testing for negative, zero, and positive. */
539 #define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0)
540 #define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0)
541 #define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0)
542
543 /* When using GCC, optimize certain common comparisons. */
544 #if defined (__GNUC__)
545 #define mpz_cmp_ui(Z,UI) \
546 (__builtin_constant_p (UI) && (UI) == 0 \
547 ? mpz_sgn (Z) : _mpz_cmp_ui (Z,UI))
548 #define mpz_cmp_si(Z,SI) \
549 (__builtin_constant_p (SI) && (SI) == 0 ? mpz_sgn (Z) \
550 : __builtin_constant_p (SI) && (SI) > 0 \
551 ? _mpz_cmp_ui (Z, (unsigned long int) SI) \
552 : _mpz_cmp_si (Z,SI))
553 #define mpq_cmp_ui(Q,NUI,DUI) \
554 (__builtin_constant_p (NUI) && (NUI) == 0 \
555 ? mpq_sgn (Q) : _mpq_cmp_ui (Q,NUI,DUI))
556 #else
557 #define mpz_cmp_ui(Z,UI) _mpz_cmp_ui (Z,UI)
558 #define mpz_cmp_si(Z,UI) _mpz_cmp_si (Z,UI)
559 #define mpq_cmp_ui(Q,NUI,DUI) _mpq_cmp_ui (Q,NUI,DUI)
560 #endif
561
562
563 /* Using "&" rather than "&&" means these can come out branch-free. Every
564 mpz_t has at least one limb allocated, so fetching the low limb is always
565 allowed. */
566 #define mpz_odd_p(z) ((int) ((z)->_mp_size != 0) & (int) (z)->_mp_d[0])
567 #define mpz_even_p(z) (! mpz_odd_p (z))
568
569
570 /* Allow direct user access to numerator and denominator of a mpq_t object. */
571 #define mpq_numref(Q) (&((Q)->_mp_num))
572 #define mpq_denref(Q) (&((Q)->_mp_den))
573
574
575 /* Compatibility with GMP 2 and earlier. */
576 #define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize)
577
578 /* Compatibility with GMP 1. */
579 #define mpz_mdiv mpz_fdiv_q
580 #define mpz_mdivmod mpz_fdiv_qr
581 #define mpz_mmod mpz_fdiv_r
582 #define mpz_mdiv_ui mpz_fdiv_q_ui
583 #define mpz_mdivmod_ui(q,r,n,d) \
584 ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d))
585 #define mpz_mmod_ui(r,n,d) \
586 ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d))
587
588 /* Useful synonyms, but not quite compatible with GMP 1. */
589 #define mpz_div mpz_fdiv_q
590 #define mpz_divmod mpz_fdiv_qr
591 #define mpz_div_ui mpz_fdiv_q_ui
592 #define mpz_divmod_ui mpz_fdiv_qr_ui
593 #define mpz_mod_ui mpz_fdiv_r_ui
594 #define mpz_div_2exp mpz_fdiv_q_2exp
595 #define mpz_mod_2exp mpz_fdiv_r_2exp
596
597 #define gmp_errno __gmp_errno
598 extern int gmp_errno;
599
600 enum
601 {
602 GMP_ERROR_NONE = 0,
603 GMP_ERROR_UNSUPPORTED_ARGUMENT = 1,
604 GMP_ERROR_DIVISION_BY_ZERO = 2,
605 GMP_ERROR_SQRT_OF_NEGATIVE = 4,
606 GMP_ERROR_INVALID_ARGUMENT = 8,
607 GMP_ERROR_ALLOCATE = 16,
608 GMP_ERROR_BAD_STRING = 32,
609 GMP_ERROR_UNUSED_ERROR
610 };
611
612 /* Note: major version number is in mp.h too */
613 #define __GNU_MP_VERSION 3
614 #define __GNU_MP_VERSION_MINOR 1
615 #define __GNU_MP_VERSION_PATCHLEVEL 1
616
617 #define gmp_version __gmp_version
618 extern __gmp_const char *gmp_version;
619
620 /* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
621 #if defined (__GNUC__) && defined (__GNUC_MINOR__)
622 #define __GMP_GNUC_PREREQ(maj, min) \
623 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
624 #else
625 #define __GMP_GNUC_PREREQ(maj, min) 0
626 #endif
627
628 #define __GMP_H__
629 #endif /* __GMP_H__ */
630