-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgmp-h.in
1300 lines (1049 loc) · 48 KB
/
gmp-h.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Definitions for GNU multiple precision functions. -*- mode: c -*-
Copyright 1991, 1993-1997, 1999-2016 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* 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.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP 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 General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#ifndef __GMP_H__
#if defined (__cplusplus)
#include <iosfwd> /* for std::istream, std::ostream, std::string */
#include <cstdio>
#endif
/* Instantiated by configure. */
#if ! defined (__GMP_WITHIN_CONFIGURE)
#define GMP_LIMB_BITS @GMP_LIMB_BITS@
#define GMP_NAIL_BITS @GMP_NAIL_BITS@
#endif
#define GMP_NUMB_BITS (GMP_LIMB_BITS - GMP_NAIL_BITS)
#define GMP_NUMB_MASK ((~ __GMP_CAST (mp_limb_t, 0)) >> GMP_NAIL_BITS)
#define GMP_NUMB_MAX GMP_NUMB_MASK
#define GMP_NAIL_MASK (~ GMP_NUMB_MASK)
#ifndef __GNU_MP__
#define __GNU_MP__ 6
#include <stddef.h> /* for size_t */
#include <limits.h>
/* Instantiated by configure. */
#if ! defined (__GMP_WITHIN_CONFIGURE)
@DEFN_LONG_LONG_LIMB@
#define __GMP_LIBGMP_DLL @LIBGMP_DLL@
#endif
/* __GMP_DECLSPEC supports Windows DLL versions of libgmp, and is empty in
all other circumstances.
When compiling objects for libgmp, __GMP_DECLSPEC is an export directive,
or when compiling for an application it's an import directive. The two
cases are differentiated by __GMP_WITHIN_GMP defined by the GMP Makefiles
(and not defined from an application).
__GMP_DECLSPEC_XX is similarly used for libgmpxx. __GMP_WITHIN_GMPXX
indicates when building libgmpxx, and in that case libgmpxx functions are
exports, but libgmp functions which might get called are imports.
Libtool DLL_EXPORT define is not used.
There's no attempt to support GMP built both static and DLL. Doing so
would mean applications would have to tell us which of the two is going
to be used when linking, and that seems very tedious and error prone if
using GMP by hand, and equally tedious from a package since autoconf and
automake don't give much help.
__GMP_DECLSPEC is required on all documented global functions and
variables, the various internals in gmp-impl.h etc can be left unadorned.
But internals used by the test programs or speed measuring programs
should have __GMP_DECLSPEC, and certainly constants or variables must
have it or the wrong address will be resolved.
In gcc __declspec can go at either the start or end of a prototype.
In Microsoft C __declspec must go at the start, or after the type like
void __declspec(...) *foo()". There's no __dllexport or anything to
guard against someone foolish #defining dllexport. _export used to be
available, but no longer.
In Borland C _export still exists, but needs to go after the type, like
"void _export foo();". Would have to change the __GMP_DECLSPEC syntax to
make use of that. Probably more trouble than it's worth. */
#if defined (__GNUC__)
#define __GMP_DECLSPEC_EXPORT __declspec(__dllexport__)
#define __GMP_DECLSPEC_IMPORT __declspec(__dllimport__)
#endif
#if defined (_MSC_VER) || defined (__BORLANDC__)
#define __GMP_DECLSPEC_EXPORT __declspec(dllexport)
#define __GMP_DECLSPEC_IMPORT __declspec(dllimport)
#endif
#ifdef __WATCOMC__
#define __GMP_DECLSPEC_EXPORT __export
#define __GMP_DECLSPEC_IMPORT __import
#endif
#ifdef __IBMC__
#define __GMP_DECLSPEC_EXPORT _Export
#define __GMP_DECLSPEC_IMPORT _Import
#endif
#if __GMP_LIBGMP_DLL
#ifdef __GMP_WITHIN_GMP
/* compiling to go into a DLL libgmp */
#define __GMP_DECLSPEC __GMP_DECLSPEC_EXPORT
#else
/* compiling to go into an application which will link to a DLL libgmp */
#define __GMP_DECLSPEC __GMP_DECLSPEC_IMPORT
#endif
#else
/* all other cases */
#define __GMP_DECLSPEC
#endif
#ifdef __GMP_SHORT_LIMB
typedef unsigned int mp_limb_t;
typedef int mp_limb_signed_t;
#else
#ifdef _LONG_LONG_LIMB
typedef unsigned long long int mp_limb_t;
typedef long long int mp_limb_signed_t;
#else
typedef unsigned long int mp_limb_t;
typedef long int mp_limb_signed_t;
#endif
#endif
typedef unsigned long int mp_bitcnt_t;
/* For reference, note that the name __mpz_struct gets into C++ mangled
function names, which means although the "__" suggests an internal, we
must leave this name for binary compatibility. */
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
#endif /* __GNU_MP__ */
typedef __mpz_struct MP_INT; /* gmp 1 source compatibility */
typedef __mpz_struct mpz_t[1];
typedef mp_limb_t * mp_ptr;
typedef const mp_limb_t * mp_srcptr;
#if defined (_CRAY) && ! defined (_CRAYMPP)
/* plain `int' is much faster (48 bits) */
#define __GMP_MP_SIZE_T_INT 1
typedef int mp_size_t;
typedef int mp_exp_t;
#else
#define __GMP_MP_SIZE_T_INT 0
typedef long int mp_size_t;
typedef long int mp_exp_t;
#endif
/* Available random number generation algorithms. */
typedef enum
{
GMP_RAND_ALG_DEFAULT = 0,
GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential. */
} gmp_randalg_t;
/* Random state struct. */
typedef struct
{
mpz_t _mp_seed; /* _mp_d member points to state of the generator. */
gmp_randalg_t _mp_alg; /* Currently unused. */
union {
void *_mp_lc; /* Pointer to function pointers structure. */
} _mp_algdata;
} __gmp_randstate_struct;
typedef __gmp_randstate_struct gmp_randstate_t[1];
/* Types for function declarations in gmp files. */
/* ??? Should not pollute user name space with these ??? */
typedef const __mpz_struct *mpz_srcptr;
typedef __mpz_struct *mpz_ptr;
#if __GMP_LIBGMP_DLL
#ifdef __GMP_WITHIN_GMPXX
/* compiling to go into a DLL libgmpxx */
#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_EXPORT
#else
/* compiling to go into a application which will link to a DLL libgmpxx */
#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_IMPORT
#endif
#else
/* all other cases */
#define __GMP_DECLSPEC_XX
#endif
#ifndef __MPN
#define __MPN(x) __gmpn_##x
#endif
/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4,
<iostream> defines EOF but not FILE. */
#if defined (FILE) \
|| defined (H_STDIO) \
|| defined (_H_STDIO) /* AIX */ \
|| defined (_STDIO_H) /* glibc, Sun, SCO */ \
|| defined (_STDIO_H_) /* BSD, OSF */ \
|| defined (__STDIO_H) /* Borland */ \
|| defined (__STDIO_H__) /* IRIX */ \
|| defined (_STDIO_INCLUDED) /* HPUX */ \
|| defined (__dj_include_stdio_h_) /* DJGPP */ \
|| defined (_FILE_DEFINED) /* Microsoft */ \
|| defined (__STDIO__) /* Apple MPW MrC */ \
|| defined (_MSL_STDIO_H) /* Metrowerks */ \
|| defined (_STDIO_H_INCLUDED) /* QNX4 */ \
|| defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \
|| defined (__STDIO_LOADED) /* VMS */ \
|| defined (__DEFINED_FILE) /* musl */
#define _GMP_H_HAVE_FILE 1
#endif
/* In ISO C, if a prototype involving "struct obstack *" is given without
that structure defined, then the struct is scoped down to just the
prototype, causing a conflict if it's subsequently defined for real. So
only give prototypes if we've got obstack.h. */
#if defined (_OBSTACK_H) /* glibc <obstack.h> */
#define _GMP_H_HAVE_OBSTACK 1
#endif
/* The prototypes for gmp_vprintf etc are provided only if va_list is defined,
via an application having included <stdarg.h>. Usually va_list is a typedef
so can't be tested directly, but C99 specifies that va_start is a macro.
<stdio.h> will define some sort of va_list for vprintf and vfprintf, but
let's not bother trying to use that since it's not standard and since
application uses for gmp_vprintf etc will almost certainly require the
whole <stdarg.h> anyway. */
#ifdef va_start
#define _GMP_H_HAVE_VA_LIST 1
#endif
/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
#if defined (__GNUC__) && defined (__GNUC_MINOR__)
#define __GMP_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
#define __GMP_GNUC_PREREQ(maj, min) 0
#endif
/* "pure" is in gcc 2.96 and up, see "(gcc)Function Attributes". Basically
it means a function does nothing but examine its arguments and memory
(global or via arguments) to generate a return value, but changes nothing
and has no side-effects. __GMP_NO_ATTRIBUTE_CONST_PURE lets
tune/common.c etc turn this off when trying to write timing loops. */
#if __GMP_GNUC_PREREQ (2,96) && ! defined (__GMP_NO_ATTRIBUTE_CONST_PURE)
#define __GMP_ATTRIBUTE_PURE __attribute__ ((__pure__))
#else
#define __GMP_ATTRIBUTE_PURE
#endif
/* __GMP_CAST allows us to use static_cast in C++, so our macros are clean
to "g++ -Wold-style-cast".
Casts in "extern inline" code within an extern "C" block don't induce
these warnings, so __GMP_CAST only needs to be used on documented
macros. */
#ifdef __cplusplus
#define __GMP_CAST(type, expr) (static_cast<type> (expr))
#else
#define __GMP_CAST(type, expr) ((type) (expr))
#endif
/* An empty "throw ()" means the function doesn't throw any C++ exceptions,
this can save some stack frame info in applications.
Currently it's given only on functions which never divide-by-zero etc,
don't allocate memory, and are expected to never need to allocate memory.
This leaves open the possibility of a C++ throw from a future GMP
exceptions scheme.
mpz_set_ui etc are omitted to leave open the lazy allocation scheme
described in doc/tasks.html. mpz_get_d etc are omitted to leave open
exceptions for float overflows.
Note that __GMP_NOTHROW must be given on any inlines the same as on their
prototypes (for g++ at least, where they're used together). Note also
that g++ 3.0 demands that __GMP_NOTHROW is before other attributes like
__GMP_ATTRIBUTE_PURE. */
#if defined (__cplusplus)
#define __GMP_NOTHROW throw ()
#else
#define __GMP_NOTHROW
#endif
/* PORTME: What other compilers have a useful "extern inline"? "static
inline" would be an acceptable substitute if the compiler (or linker)
discards unused statics. */
/* gcc has __inline__ in all modes, including strict ansi. Give a prototype
for an inline too, so as to correctly specify "dllimport" on windows, in
case the function is called rather than inlined.
GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
inline semantics, unless -fgnu89-inline is used. */
#ifdef __GNUC__
#if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2) \
|| (defined __GNUC_GNU_INLINE__ && defined __cplusplus)
#define __GMP_EXTERN_INLINE extern __inline__ __attribute__ ((__gnu_inline__))
#else
#define __GMP_EXTERN_INLINE extern __inline__
#endif
#define __GMP_INLINE_PROTOTYPES 1
#endif
/* DEC C (eg. version 5.9) supports "static __inline foo()", even in -std1
strict ANSI mode. Inlining is done even when not optimizing (ie. -O0
mode, which is the default), but an unnecessary local copy of foo is
emitted unless -O is used. "extern __inline" is accepted, but the
"extern" appears to be ignored, ie. it becomes a plain global function
but which is inlined within its file. Don't know if all old versions of
DEC C supported __inline, but as a start let's do the right thing for
current versions. */
#ifdef __DECC
#define __GMP_EXTERN_INLINE static __inline
#endif
/* SCO OpenUNIX 8 cc supports "static inline foo()" but not in -Xc strict
ANSI mode (__STDC__ is 1 in that mode). Inlining only actually takes
place under -O. Without -O "foo" seems to be emitted whether it's used
or not, which is wasteful. "extern inline foo()" isn't useful, the
"extern" is apparently ignored, so foo is inlined if possible but also
emitted as a global, which causes multiple definition errors when
building a shared libgmp. */
#ifdef __SCO_VERSION__
#if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \
&& ! defined (__GMP_EXTERN_INLINE)
#define __GMP_EXTERN_INLINE static inline
#endif
#endif
/* Microsoft's C compiler accepts __inline */
#ifdef _MSC_VER
#define __GMP_EXTERN_INLINE __inline
#endif
/* Recent enough Sun C compilers want "inline" */
#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560 \
&& ! defined (__GMP_EXTERN_INLINE)
#define __GMP_EXTERN_INLINE inline
#endif
/* Somewhat older Sun C compilers want "static inline" */
#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540 \
&& ! defined (__GMP_EXTERN_INLINE)
#define __GMP_EXTERN_INLINE static inline
#endif
/* C++ always has "inline" and since it's a normal feature the linker should
discard duplicate non-inlined copies, or if it doesn't then that's a
problem for everyone, not just GMP. */
#if defined (__cplusplus) && ! defined (__GMP_EXTERN_INLINE)
#define __GMP_EXTERN_INLINE inline
#endif
/* Don't do any inlining within a configure run, since if the compiler ends
up emitting copies of the code into the object file it can end up
demanding the various support routines (like mpn_popcount) for linking,
making the "alloca" test and perhaps others fail. And on hppa ia64 a
pre-release gcc 3.2 was seen not respecting the "extern" in "extern
__inline__", triggering this problem too. */
#if defined (__GMP_WITHIN_CONFIGURE) && ! __GMP_WITHIN_CONFIGURE_INLINE
#undef __GMP_EXTERN_INLINE
#endif
/* By default, don't give a prototype when there's going to be an inline
version. Note in particular that Cray C++ objects to the combination of
prototype and inline. */
#ifdef __GMP_EXTERN_INLINE
#ifndef __GMP_INLINE_PROTOTYPES
#define __GMP_INLINE_PROTOTYPES 0
#endif
#else
#define __GMP_INLINE_PROTOTYPES 1
#endif
#define __GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
#define __GMP_MAX(h,i) ((h) > (i) ? (h) : (i))
/* __builtin_expect is in gcc 3.0, and not in 2.95. */
#if __GMP_GNUC_PREREQ (3,0)
#define __GMP_LIKELY(cond) __builtin_expect ((cond) != 0, 1)
#define __GMP_UNLIKELY(cond) __builtin_expect ((cond) != 0, 0)
#else
#define __GMP_LIKELY(cond) (cond)
#define __GMP_UNLIKELY(cond) (cond)
#endif
#ifdef _CRAY
#define __GMP_CRAY_Pragma(str) _Pragma (str)
#else
#define __GMP_CRAY_Pragma(str)
#endif
#define mp_set_memory_functions __gmp_set_memory_functions
__GMP_DECLSPEC void mp_set_memory_functions (void *(*) (size_t),
void *(*) (void *, size_t, size_t),
void (*) (void *, size_t)) __GMP_NOTHROW;
#define mp_get_memory_functions __gmp_get_memory_functions
__GMP_DECLSPEC void mp_get_memory_functions (void *(**) (size_t),
void *(**) (void *, size_t, size_t),
void (**) (void *, size_t)) __GMP_NOTHROW;
#define mp_bits_per_limb __gmp_bits_per_limb
__GMP_DECLSPEC extern const int mp_bits_per_limb;
#define gmp_errno __gmp_errno
__GMP_DECLSPEC extern int gmp_errno;
#define gmp_version __gmp_version
__GMP_DECLSPEC extern const char * const gmp_version;
/**************** Integer (i.e. Z) routines. ****************/
#define _mpz_realloc __gmpz_realloc
#define mpz_realloc __gmpz_realloc
__GMP_DECLSPEC void *_mpz_realloc (mpz_ptr, mp_size_t);
#define mpz_add __gmpz_add
__GMP_DECLSPEC void mpz_add (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_add_ui __gmpz_add_ui
__GMP_DECLSPEC void mpz_add_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_cdiv_q __gmpz_cdiv_q
__GMP_DECLSPEC void mpz_cdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_cdiv_q_2exp __gmpz_cdiv_q_2exp
__GMP_DECLSPEC void mpz_cdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
#define mpz_cdiv_q_ui __gmpz_cdiv_q_ui
__GMP_DECLSPEC unsigned long int mpz_cdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_clear __gmpz_clear
__GMP_DECLSPEC void mpz_clear (mpz_ptr);
#define mpz_clears __gmpz_clears
__GMP_DECLSPEC void mpz_clears (mpz_ptr, ...);
#define mpz_cmp __gmpz_cmp
__GMP_DECLSPEC int mpz_cmp (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define _mpz_cmp_si __gmpz_cmp_si
__GMP_DECLSPEC int _mpz_cmp_si (mpz_srcptr, signed long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define _mpz_cmp_ui __gmpz_cmp_ui
__GMP_DECLSPEC int _mpz_cmp_ui (mpz_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpz_divexact __gmpz_divexact
__GMP_DECLSPEC void mpz_divexact (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_divexact_ui __gmpz_divexact_ui
__GMP_DECLSPEC void mpz_divexact_ui (mpz_ptr, mpz_srcptr, unsigned long);
#define mpz_export __gmpz_export
__GMP_DECLSPEC void *mpz_export (void *, size_t *, int, size_t, int, size_t, mpz_srcptr);
#define mpz_fdiv_q_2exp __gmpz_fdiv_q_2exp
__GMP_DECLSPEC void mpz_fdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
#define mpz_fdiv_q_ui __gmpz_fdiv_q_ui
__GMP_DECLSPEC unsigned long int mpz_fdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_fdiv_r_ui __gmpz_fdiv_r_ui
__GMP_DECLSPEC unsigned long int mpz_fdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_gcdext __gmpz_gcdext
__GMP_DECLSPEC void mpz_gcdext (mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_get_str __gmpz_get_str
__GMP_DECLSPEC char *mpz_get_str (char *, int, mpz_srcptr);
#define mpz_get_ui __gmpz_get_ui
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_get_ui)
__GMP_DECLSPEC unsigned long int mpz_get_ui (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#endif
#define mpz_getlimbn __gmpz_getlimbn
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_getlimbn)
__GMP_DECLSPEC mp_limb_t mpz_getlimbn (mpz_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#endif
#define mpz_import __gmpz_import
__GMP_DECLSPEC void mpz_import (mpz_ptr, size_t, int, size_t, int, size_t, const void *);
#define mpz_init __gmpz_init
__GMP_DECLSPEC void mpz_init (mpz_ptr);
#define mpz_inits __gmpz_inits
__GMP_DECLSPEC void mpz_inits (mpz_ptr, ...);
#define mpz_init_set __gmpz_init_set
__GMP_DECLSPEC void mpz_init_set (mpz_ptr, mpz_srcptr);
#define mpz_init_set_ui __gmpz_init_set_ui
__GMP_DECLSPEC void mpz_init_set_ui (mpz_ptr, unsigned long int);
#define mpz_invert __gmpz_invert
__GMP_DECLSPEC int mpz_invert (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_mod __gmpz_mod
__GMP_DECLSPEC void mpz_mod (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_mod_ui mpz_fdiv_r_ui /* same as fdiv_r because divisor unsigned */
#define mpz_mul __gmpz_mul
__GMP_DECLSPEC void mpz_mul (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_mul_ui __gmpz_mul_ui
__GMP_DECLSPEC void mpz_mul_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_neg __gmpz_neg
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_neg)
__GMP_DECLSPEC void mpz_neg (mpz_ptr, mpz_srcptr);
#endif
#define mpz_pow_ui __gmpz_pow_ui
__GMP_DECLSPEC void mpz_pow_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_powm __gmpz_powm
__GMP_DECLSPEC void mpz_powm (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr);
#define mpz_powm_ui __gmpz_powm_ui
__GMP_DECLSPEC void mpz_powm_ui (mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr);
#define mpz_realloc2 __gmpz_realloc2
__GMP_DECLSPEC void mpz_realloc2 (mpz_ptr, mp_bitcnt_t);
#define mpz_scan1 __gmpz_scan1
__GMP_DECLSPEC mp_bitcnt_t mpz_scan1 (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpz_set __gmpz_set
__GMP_DECLSPEC void mpz_set (mpz_ptr, mpz_srcptr);
#define mpz_set_si __gmpz_set_si
__GMP_DECLSPEC void mpz_set_si (mpz_ptr, signed long int);
#define mpz_set_str __gmpz_set_str
__GMP_DECLSPEC int mpz_set_str (mpz_ptr, const char *, int);
#define mpz_set_ui __gmpz_set_ui
__GMP_DECLSPEC void mpz_set_ui (mpz_ptr, unsigned long int);
#define mpz_sizeinbase __gmpz_sizeinbase
__GMP_DECLSPEC size_t mpz_sizeinbase (mpz_srcptr, int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpz_sub __gmpz_sub
__GMP_DECLSPEC void mpz_sub (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_sub_ui __gmpz_sub_ui
__GMP_DECLSPEC void mpz_sub_ui (mpz_ptr, mpz_srcptr, unsigned long int);
#define mpz_tdiv_q_2exp __gmpz_tdiv_q_2exp
__GMP_DECLSPEC void mpz_tdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
#define mpz_tdiv_qr __gmpz_tdiv_qr
__GMP_DECLSPEC void mpz_tdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_tdiv_r __gmpz_tdiv_r
__GMP_DECLSPEC void mpz_tdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr);
#define mpz_tstbit __gmpz_tstbit
__GMP_DECLSPEC int mpz_tstbit (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpz_ui_pow_ui __gmpz_ui_pow_ui
__GMP_DECLSPEC void mpz_ui_pow_ui (mpz_ptr, unsigned long int, unsigned long int);
/************ Low level positive-integer (i.e. N) routines. ************/
/* This is ugly, but we need to make user calls reach the prefixed function. */
#define mpn_add __MPN(add)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add)
__GMP_DECLSPEC mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
#endif
#define mpn_add_1 __MPN(add_1)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add_1)
__GMP_DECLSPEC mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW;
#endif
#define mpn_add_n __MPN(add_n)
__GMP_DECLSPEC mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_addmul_1 __MPN(addmul_1)
__GMP_DECLSPEC mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_cmp __MPN(cmp)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_cmp)
__GMP_DECLSPEC int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#endif
#define mpn_zero_p __MPN(zero_p)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_zero_p)
__GMP_DECLSPEC int mpn_zero_p (mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#endif
#define mpn_divexact_1 __MPN(divexact_1)
__GMP_DECLSPEC void mpn_divexact_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_divexact_by3(dst,src,size) \
mpn_divexact_by3c (dst, src, size, __GMP_CAST (mp_limb_t, 0))
#define mpn_divexact_by3c __MPN(divexact_by3c)
__GMP_DECLSPEC mp_limb_t mpn_divexact_by3c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_divmod_1(qp,np,nsize,dlimb) \
mpn_divrem_1 (qp, __GMP_CAST (mp_size_t, 0), np, nsize, dlimb)
#define mpn_divrem __MPN(divrem)
__GMP_DECLSPEC mp_limb_t mpn_divrem (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
#define mpn_divrem_1 __MPN(divrem_1)
__GMP_DECLSPEC mp_limb_t mpn_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_divrem_2 __MPN(divrem_2)
__GMP_DECLSPEC mp_limb_t mpn_divrem_2 (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr);
#define mpn_div_qr_1 __MPN(div_qr_1)
__GMP_DECLSPEC mp_limb_t mpn_div_qr_1 (mp_ptr, mp_limb_t *, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_div_qr_2 __MPN(div_qr_2)
__GMP_DECLSPEC mp_limb_t mpn_div_qr_2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
#define mpn_gcd __MPN(gcd)
__GMP_DECLSPEC mp_size_t mpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
#define mpn_gcd_1 __MPN(gcd_1)
__GMP_DECLSPEC mp_limb_t mpn_gcd_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
#define mpn_gcdext_1 __MPN(gcdext_1)
__GMP_DECLSPEC mp_limb_t mpn_gcdext_1 (mp_limb_signed_t *, mp_limb_signed_t *, mp_limb_t, mp_limb_t);
#define mpn_gcdext __MPN(gcdext)
__GMP_DECLSPEC mp_size_t mpn_gcdext (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
#define mpn_get_str __MPN(get_str)
__GMP_DECLSPEC size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t);
#define mpn_hamdist __MPN(hamdist)
__GMP_DECLSPEC mp_bitcnt_t mpn_hamdist (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpn_lshift __MPN(lshift)
__GMP_DECLSPEC mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
#define mpn_mod_1 __MPN(mod_1)
__GMP_DECLSPEC mp_limb_t mpn_mod_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
#define mpn_mul __MPN(mul)
__GMP_DECLSPEC mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
#define mpn_mul_1 __MPN(mul_1)
__GMP_DECLSPEC mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_mul_n __MPN(mul_n)
__GMP_DECLSPEC void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_sqr __MPN(sqr)
__GMP_DECLSPEC void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
#define mpn_neg __MPN(neg)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_neg)
__GMP_DECLSPEC mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t);
#endif
#define mpn_com __MPN(com)
__GMP_DECLSPEC void mpn_com (mp_ptr, mp_srcptr, mp_size_t);
#define mpn_perfect_square_p __MPN(perfect_square_p)
__GMP_DECLSPEC int mpn_perfect_square_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_perfect_power_p __MPN(perfect_power_p)
__GMP_DECLSPEC int mpn_perfect_power_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_popcount __MPN(popcount)
__GMP_DECLSPEC mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
#define mpn_pow_1 __MPN(pow_1)
__GMP_DECLSPEC mp_size_t mpn_pow_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
/* undocumented now, but retained here for upward compatibility */
#define mpn_preinv_mod_1 __MPN(preinv_mod_1)
__GMP_DECLSPEC mp_limb_t mpn_preinv_mod_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
#define mpn_random __MPN(random)
__GMP_DECLSPEC void mpn_random (mp_ptr, mp_size_t);
#define mpn_random2 __MPN(random2)
__GMP_DECLSPEC void mpn_random2 (mp_ptr, mp_size_t);
#define mpn_rshift __MPN(rshift)
__GMP_DECLSPEC mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
#define mpn_scan0 __MPN(scan0)
__GMP_DECLSPEC mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE;
#define mpn_scan1 __MPN(scan1)
__GMP_DECLSPEC mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE;
#define mpn_set_str __MPN(set_str)
__GMP_DECLSPEC mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int);
#define mpn_sizeinbase __MPN(sizeinbase)
__GMP_DECLSPEC size_t mpn_sizeinbase (mp_srcptr, mp_size_t, int);
#define mpn_sqrtrem __MPN(sqrtrem)
__GMP_DECLSPEC mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t);
#define mpn_sub __MPN(sub)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub)
__GMP_DECLSPEC mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
#endif
#define mpn_sub_1 __MPN(sub_1)
#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub_1)
__GMP_DECLSPEC mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW;
#endif
#define mpn_sub_n __MPN(sub_n)
__GMP_DECLSPEC mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_submul_1 __MPN(submul_1)
__GMP_DECLSPEC mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
#define mpn_tdiv_qr __MPN(tdiv_qr)
__GMP_DECLSPEC void mpn_tdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
#define mpn_and_n __MPN(and_n)
__GMP_DECLSPEC void mpn_and_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_andn_n __MPN(andn_n)
__GMP_DECLSPEC void mpn_andn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_nand_n __MPN(nand_n)
__GMP_DECLSPEC void mpn_nand_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_ior_n __MPN(ior_n)
__GMP_DECLSPEC void mpn_ior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_iorn_n __MPN(iorn_n)
__GMP_DECLSPEC void mpn_iorn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_nior_n __MPN(nior_n)
__GMP_DECLSPEC void mpn_nior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_xor_n __MPN(xor_n)
__GMP_DECLSPEC void mpn_xor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_xnor_n __MPN(xnor_n)
__GMP_DECLSPEC void mpn_xnor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_copyi __MPN(copyi)
__GMP_DECLSPEC void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
#define mpn_copyd __MPN(copyd)
__GMP_DECLSPEC void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
#define mpn_zero __MPN(zero)
__GMP_DECLSPEC void mpn_zero (mp_ptr, mp_size_t);
#define mpn_cnd_add_n __MPN(cnd_add_n)
__GMP_DECLSPEC mp_limb_t mpn_cnd_add_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_cnd_sub_n __MPN(cnd_sub_n)
__GMP_DECLSPEC mp_limb_t mpn_cnd_sub_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
#define mpn_sec_add_1 __MPN(sec_add_1)
__GMP_DECLSPEC mp_limb_t mpn_sec_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
#define mpn_sec_add_1_itch __MPN(sec_add_1_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_add_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_sub_1 __MPN(sec_sub_1)
__GMP_DECLSPEC mp_limb_t mpn_sec_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
#define mpn_sec_sub_1_itch __MPN(sec_sub_1_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_sub_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_cnd_swap __MPN(cnd_swap)
__GMP_DECLSPEC void mpn_cnd_swap (mp_limb_t, volatile mp_limb_t *, volatile mp_limb_t *, mp_size_t);
#define mpn_sec_mul __MPN(sec_mul)
__GMP_DECLSPEC void mpn_sec_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
#define mpn_sec_mul_itch __MPN(sec_mul_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_mul_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_sqr __MPN(sec_sqr)
__GMP_DECLSPEC void mpn_sec_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
#define mpn_sec_sqr_itch __MPN(sec_sqr_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_sqr_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_powm __MPN(sec_powm)
__GMP_DECLSPEC void mpn_sec_powm (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_bitcnt_t, mp_srcptr, mp_size_t, mp_ptr);
#define mpn_sec_powm_itch __MPN(sec_powm_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_powm_itch (mp_size_t, mp_bitcnt_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_tabselect __MPN(sec_tabselect)
__GMP_DECLSPEC void mpn_sec_tabselect (volatile mp_limb_t *, volatile const mp_limb_t *, mp_size_t, mp_size_t, mp_size_t);
#define mpn_sec_div_qr __MPN(sec_div_qr)
__GMP_DECLSPEC mp_limb_t mpn_sec_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
#define mpn_sec_div_qr_itch __MPN(sec_div_qr_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_div_qr_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_div_r __MPN(sec_div_r)
__GMP_DECLSPEC void mpn_sec_div_r (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
#define mpn_sec_div_r_itch __MPN(sec_div_r_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_div_r_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
#define mpn_sec_invert __MPN(sec_invert)
__GMP_DECLSPEC int mpn_sec_invert (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_bitcnt_t, mp_ptr);
#define mpn_sec_invert_itch __MPN(sec_invert_itch)
__GMP_DECLSPEC mp_size_t mpn_sec_invert_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
/**************** mpz inlines ****************/
/* The following are provided as inlines where possible, but always exist as
library functions too, for binary compatibility.
Within gmp itself this inlining generally isn't relied on, since it
doesn't get done for all compilers, whereas if something is worth
inlining then it's worth arranging always.
There are two styles of inlining here. When the same bit of code is
wanted for the inline as for the library version, then __GMP_FORCE_foo
arranges for that code to be emitted and the __GMP_EXTERN_INLINE
directive suppressed, eg. mpz_fits_uint_p. When a different bit of code
is wanted for the inline than for the library version, then
__GMP_FORCE_foo arranges the inline to be suppressed, eg. mpz_abs. */
#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_get_ui)
#if ! defined (__GMP_FORCE_mpz_get_ui)
__GMP_EXTERN_INLINE
#endif
unsigned long
mpz_get_ui (mpz_srcptr __gmp_z) __GMP_NOTHROW
{
mp_ptr __gmp_p = __gmp_z->_mp_d;
mp_size_t __gmp_n = __gmp_z->_mp_size;
mp_limb_t __gmp_l = __gmp_p[0];
/* This is a "#if" rather than a plain "if" so as to avoid gcc warnings
about "<< GMP_NUMB_BITS" exceeding the type size, and to avoid Borland
C++ 6.0 warnings about condition always true for something like
"ULONG_MAX < GMP_NUMB_MASK". */
#if GMP_NAIL_BITS == 0 || defined (_LONG_LONG_LIMB)
/* limb==long and no nails, or limb==longlong, one limb is enough */
return (__gmp_n != 0 ? __gmp_l : 0);
#else
/* limb==long and nails, need two limbs when available */
__gmp_n = __GMP_ABS (__gmp_n);
if (__gmp_n <= 1)
return (__gmp_n != 0 ? __gmp_l : 0);
else
return __gmp_l + (__gmp_p[1] << GMP_NUMB_BITS);
#endif
}
#endif
#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_getlimbn)
#if ! defined (__GMP_FORCE_mpz_getlimbn)
__GMP_EXTERN_INLINE
#endif
mp_limb_t
mpz_getlimbn (mpz_srcptr __gmp_z, mp_size_t __gmp_n) __GMP_NOTHROW
{
mp_limb_t __gmp_result = 0;
if (__GMP_LIKELY (__gmp_n >= 0 && __gmp_n < __GMP_ABS (__gmp_z->_mp_size)))
__gmp_result = __gmp_z->_mp_d[__gmp_n];
return __gmp_result;
}
#endif
#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpz_neg)
__GMP_EXTERN_INLINE void
mpz_neg (mpz_ptr __gmp_w, mpz_srcptr __gmp_u)
{
if (__gmp_w != __gmp_u)
mpz_set (__gmp_w, __gmp_u);
__gmp_w->_mp_size = - __gmp_w->_mp_size;
}
#endif
/**************** mpn inlines ****************/
/* The comments with __GMPN_ADD_1 below apply here too.
The test for FUNCTION returning 0 should predict well. If it's assumed
{yp,ysize} will usually have a random number of bits then the high limb
won't be full and a carry out will occur a good deal less than 50% of the
time.
ysize==0 isn't a documented feature, but is used internally in a few
places.
Producing cout last stops it using up a register during the main part of
the calculation, though gcc (as of 3.0) on an "if (mpn_add (...))"
doesn't seem able to move the true and false legs of the conditional up
to the two places cout is generated. */
#define __GMPN_AORS(cout, wp, xp, xsize, yp, ysize, FUNCTION, TEST) \
do { \
mp_size_t __gmp_i; \
mp_limb_t __gmp_x; \
\
/* ASSERT ((ysize) >= 0); */ \
/* ASSERT ((xsize) >= (ysize)); */ \
/* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, xp, xsize)); */ \
/* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, yp, ysize)); */ \
\
__gmp_i = (ysize); \
if (__gmp_i != 0) \
{ \
if (FUNCTION (wp, xp, yp, __gmp_i)) \
{ \
do \
{ \
if (__gmp_i >= (xsize)) \
{ \
(cout) = 1; \
goto __gmp_done; \
} \
__gmp_x = (xp)[__gmp_i]; \
} \
while (TEST); \
} \
} \
if ((wp) != (xp)) \
__GMPN_COPY_REST (wp, xp, xsize, __gmp_i); \
(cout) = 0; \
__gmp_done: \
; \
} while (0)
#define __GMPN_ADD(cout, wp, xp, xsize, yp, ysize) \
__GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_add_n, \
(((wp)[__gmp_i++] = (__gmp_x + 1) & GMP_NUMB_MASK) == 0))
#define __GMPN_SUB(cout, wp, xp, xsize, yp, ysize) \
__GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_sub_n, \
(((wp)[__gmp_i++] = (__gmp_x - 1) & GMP_NUMB_MASK), __gmp_x == 0))
/* The use of __gmp_i indexing is designed to ensure a compile time src==dst
remains nice and clear to the compiler, so that __GMPN_COPY_REST can
disappear, and the load/add/store gets a chance to become a
read-modify-write on CISC CPUs.
Alternatives:
Using a pair of pointers instead of indexing would be possible, but gcc
isn't able to recognise compile-time src==dst in that case, even when the
pointers are incremented more or less together. Other compilers would
very likely have similar difficulty.
gcc could use "if (__builtin_constant_p(src==dst) && src==dst)" or
similar to detect a compile-time src==dst. This works nicely on gcc
2.95.x, it's not good on gcc 3.0 where __builtin_constant_p(p==p) seems
to be always false, for a pointer p. But the current code form seems
good enough for src==dst anyway.
gcc on x86 as usual doesn't give particularly good flags handling for the
carry/borrow detection. It's tempting to want some multi instruction asm
blocks to help it, and this was tried, but in truth there's only a few
instructions to save and any gain is all too easily lost by register
juggling setting up for the asm. */
#if GMP_NAIL_BITS == 0
#define __GMPN_AORS_1(cout, dst, src, n, v, OP, CB) \
do { \
mp_size_t __gmp_i; \
mp_limb_t __gmp_x, __gmp_r; \
\
/* ASSERT ((n) >= 1); */ \
/* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, n)); */ \