aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2020-01-26 12:52:56 -0800
committerPaul Eggert2020-01-26 12:54:47 -0800
commit901f58ce5f4603e14f4cd1bb64d4d5cf06985b89 (patch)
treea989ee9fde6d9d09e4682fd754f70ed1e2d77fae
parent491c909175eb9ff99ff3fdf766e81b333b9d316a (diff)
downloademacs-901f58ce5f4603e14f4cd1bb64d4d5cf06985b89.tar.gz
emacs-901f58ce5f4603e14f4cd1bb64d4d5cf06985b89.zip
Update mini-gmp
* src/mini-gmp.c, src/mini-gmp.h: Copy from GMP 6.2.0. This incorporates: 2019-12-05 remove some sizeof(mp_limb_t) 2019-12-04 (mpn_invert_3by2): Remove special code for limb sizes 2019-12-04 (mpn_invert_3by2): Limit size of an intermediate 2019-11-20 (mpn_invert_3by2): Use xor instead of negation 2019-11-19 (mpn_invert_3by2): Move an assert earlier 2019-11-19 (mpn_invert_3by2): Add a new shortcut 2019-11-17 Prepend "unsigned" to MINI_GMP_LIMB_TYPE 2019-11-17 Enable testing with different limb sizes (types) 2019-11-20 Use already defined constants 2019-11-09 Avoid undefined behaviour with small limb sizes
-rw-r--r--src/mini-gmp.c222
-rw-r--r--src/mini-gmp.h8
2 files changed, 123 insertions, 107 deletions
diff --git a/src/mini-gmp.c b/src/mini-gmp.c
index bf8a6164981..09c5436be0a 100644
--- a/src/mini-gmp.c
+++ b/src/mini-gmp.c
@@ -94,11 +94,13 @@ see https://www.gnu.org/licenses/. */
94 94
95#define gmp_clz(count, x) do { \ 95#define gmp_clz(count, x) do { \
96 mp_limb_t __clz_x = (x); \ 96 mp_limb_t __clz_x = (x); \
97 unsigned __clz_c; \ 97 unsigned __clz_c = 0; \
98 for (__clz_c = 0; \ 98 int LOCAL_SHIFT_BITS = 8; \
99 (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \ 99 if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS) \
100 __clz_c += 8) \ 100 for (; \
101 __clz_x <<= 8; \ 101 (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \
102 __clz_c += 8) \
103 { __clz_x <<= LOCAL_SHIFT_BITS; } \
102 for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \ 104 for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \
103 __clz_x <<= 1; \ 105 __clz_x <<= 1; \
104 (count) = __clz_c; \ 106 (count) = __clz_c; \
@@ -143,27 +145,27 @@ see https://www.gnu.org/licenses/. */
143 w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ 145 w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \
144 } \ 146 } \
145 else { \ 147 else { \
146 mp_limb_t __x0, __x1, __x2, __x3; \ 148 mp_limb_t __x0, __x1, __x2, __x3; \
147 unsigned __ul, __vl, __uh, __vh; \ 149 unsigned __ul, __vl, __uh, __vh; \
148 mp_limb_t __u = (u), __v = (v); \ 150 mp_limb_t __u = (u), __v = (v); \
149 \ 151 \
150 __ul = __u & GMP_LLIMB_MASK; \ 152 __ul = __u & GMP_LLIMB_MASK; \
151 __uh = __u >> (GMP_LIMB_BITS / 2); \ 153 __uh = __u >> (GMP_LIMB_BITS / 2); \
152 __vl = __v & GMP_LLIMB_MASK; \ 154 __vl = __v & GMP_LLIMB_MASK; \
153 __vh = __v >> (GMP_LIMB_BITS / 2); \ 155 __vh = __v >> (GMP_LIMB_BITS / 2); \
154 \ 156 \
155 __x0 = (mp_limb_t) __ul * __vl; \ 157 __x0 = (mp_limb_t) __ul * __vl; \
156 __x1 = (mp_limb_t) __ul * __vh; \ 158 __x1 = (mp_limb_t) __ul * __vh; \
157 __x2 = (mp_limb_t) __uh * __vl; \ 159 __x2 = (mp_limb_t) __uh * __vl; \
158 __x3 = (mp_limb_t) __uh * __vh; \ 160 __x3 = (mp_limb_t) __uh * __vh; \
159 \ 161 \
160 __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \ 162 __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \
161 __x1 += __x2; /* but this indeed can */ \ 163 __x1 += __x2; /* but this indeed can */ \
162 if (__x1 < __x2) /* did we get it? */ \ 164 if (__x1 < __x2) /* did we get it? */ \
163 __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \ 165 __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \
164 \ 166 \
165 (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ 167 (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \
166 (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ 168 (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \
167 } \ 169 } \
168 } while (0) 170 } while (0)
169 171
@@ -768,91 +770,81 @@ mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n)
768mp_limb_t 770mp_limb_t
769mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) 771mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
770{ 772{
771 int GMP_LIMB_BITS_MUL_3 = GMP_LIMB_BITS * 3; 773 mp_limb_t r, m;
772 if (sizeof (unsigned) * CHAR_BIT > GMP_LIMB_BITS * 3)
773 {
774 return (((unsigned) 1 << GMP_LIMB_BITS_MUL_3) - 1) /
775 (((unsigned) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0);
776 }
777 else if (GMP_ULONG_BITS > GMP_LIMB_BITS * 3)
778 {
779 return (((unsigned long) 1 << GMP_LIMB_BITS_MUL_3) - 1) /
780 (((unsigned long) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0);
781 }
782 else {
783 mp_limb_t r, p, m, ql;
784 unsigned ul, uh, qh;
785 774
786 assert (u1 >= GMP_LIMB_HIGHBIT); 775 {
776 mp_limb_t p, ql;
777 unsigned ul, uh, qh;
787 778
788 /* For notation, let b denote the half-limb base, so that B = b^2. 779 /* For notation, let b denote the half-limb base, so that B = b^2.
789 Split u1 = b uh + ul. */ 780 Split u1 = b uh + ul. */
790 ul = u1 & GMP_LLIMB_MASK; 781 ul = u1 & GMP_LLIMB_MASK;
791 uh = u1 >> (GMP_LIMB_BITS / 2); 782 uh = u1 >> (GMP_LIMB_BITS / 2);
792 783
793 /* Approximation of the high half of quotient. Differs from the 2/1 784 /* Approximation of the high half of quotient. Differs from the 2/1
794 inverse of the half limb uh, since we have already subtracted 785 inverse of the half limb uh, since we have already subtracted
795 u0. */ 786 u0. */
796 qh = ~u1 / uh; 787 qh = (u1 ^ GMP_LIMB_MAX) / uh;
797 788
798 /* Adjust to get a half-limb 3/2 inverse, i.e., we want 789 /* Adjust to get a half-limb 3/2 inverse, i.e., we want
799 790
800 qh' = floor( (b^3 - 1) / u) - b = floor ((b^3 - b u - 1) / u 791 qh' = floor( (b^3 - 1) / u) - b = floor ((b^3 - b u - 1) / u
801 = floor( (b (~u) + b-1) / u), 792 = floor( (b (~u) + b-1) / u),
802 793
803 and the remainder 794 and the remainder
804 795
805 r = b (~u) + b-1 - qh (b uh + ul) 796 r = b (~u) + b-1 - qh (b uh + ul)
806 = b (~u - qh uh) + b-1 - qh ul 797 = b (~u - qh uh) + b-1 - qh ul
807 798
808 Subtraction of qh ul may underflow, which implies adjustments. 799 Subtraction of qh ul may underflow, which implies adjustments.
809 But by normalization, 2 u >= B > qh ul, so we need to adjust by 800 But by normalization, 2 u >= B > qh ul, so we need to adjust by
810 at most 2. 801 at most 2.
811 */ 802 */
812 803
813 r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK; 804 r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK;
814 805
815 p = (mp_limb_t) qh * ul; 806 p = (mp_limb_t) qh * ul;
816 /* Adjustment steps taken from udiv_qrnnd_c */ 807 /* Adjustment steps taken from udiv_qrnnd_c */
817 if (r < p) 808 if (r < p)
818 { 809 {
819 qh--; 810 qh--;
820 r += u1; 811 r += u1;
821 if (r >= u1) /* i.e. we didn't get carry when adding to r */ 812 if (r >= u1) /* i.e. we didn't get carry when adding to r */
822 if (r < p) 813 if (r < p)
823 { 814 {
824 qh--; 815 qh--;
825 r += u1; 816 r += u1;
826 } 817 }
827 } 818 }
828 r -= p; 819 r -= p;
829 820
830 /* Low half of the quotient is 821 /* Low half of the quotient is
831 822
832 ql = floor ( (b r + b-1) / u1). 823 ql = floor ( (b r + b-1) / u1).
833 824
834 This is a 3/2 division (on half-limbs), for which qh is a 825 This is a 3/2 division (on half-limbs), for which qh is a
835 suitable inverse. */ 826 suitable inverse. */
836 827
837 p = (r >> (GMP_LIMB_BITS / 2)) * qh + r; 828 p = (r >> (GMP_LIMB_BITS / 2)) * qh + r;
838 /* Unlike full-limb 3/2, we can add 1 without overflow. For this to 829 /* Unlike full-limb 3/2, we can add 1 without overflow. For this to
839 work, it is essential that ql is a full mp_limb_t. */ 830 work, it is essential that ql is a full mp_limb_t. */
840 ql = (p >> (GMP_LIMB_BITS / 2)) + 1; 831 ql = (p >> (GMP_LIMB_BITS / 2)) + 1;
841 832
842 /* By the 3/2 trick, we don't need the high half limb. */ 833 /* By the 3/2 trick, we don't need the high half limb. */
843 r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1; 834 r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1;
844 835
845 if (r >= (p << (GMP_LIMB_BITS / 2))) 836 if (r >= (GMP_LIMB_MAX & (p << (GMP_LIMB_BITS / 2))))
846 { 837 {
847 ql--; 838 ql--;
848 r += u1; 839 r += u1;
849 } 840 }
850 m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql; 841 m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql;
851 if (r >= u1) 842 if (r >= u1)
852 { 843 {
853 m++; 844 m++;
854 r -= u1; 845 r -= u1;
855 } 846 }
847 }
856 848
857 /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a 849 /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a
858 3/2 inverse. */ 850 3/2 inverse. */
@@ -881,7 +873,6 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
881 } 873 }
882 874
883 return m; 875 return m;
884 }
885} 876}
886 877
887struct gmp_div_inverse 878struct gmp_div_inverse
@@ -3332,7 +3323,7 @@ mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k)
3332 mpz_fac_ui (t, k); 3323 mpz_fac_ui (t, k);
3333 3324
3334 for (; k > 0; --k) 3325 for (; k > 0; --k)
3335 mpz_mul_ui (r, r, n--); 3326 mpz_mul_ui (r, r, n--);
3336 3327
3337 mpz_divexact (r, r, t); 3328 mpz_divexact (r, r, t);
3338 mpz_clear (t); 3329 mpz_clear (t);
@@ -3427,7 +3418,7 @@ gmp_lucas_mod (mpz_t V, mpz_t Qk, long Q,
3427 gmp_lucas_step_k_2k (V, Qk, n); 3418 gmp_lucas_step_k_2k (V, Qk, n);
3428 3419
3429 /* A step k->k+1 is performed if the bit in $n$ is 1 */ 3420 /* A step k->k+1 is performed if the bit in $n$ is 1 */
3430 /* mpz_tstbit(n,bs) or the bit is 0 in $n$ but */ 3421 /* mpz_tstbit(n,bs) or the the bit is 0 in $n$ but */
3431 /* should be 1 in $n+1$ (bs == b0) */ 3422 /* should be 1 in $n+1$ (bs == b0) */
3432 if (b0 == bs || mpz_tstbit (n, bs)) 3423 if (b0 == bs || mpz_tstbit (n, bs))
3433 { 3424 {
@@ -3990,13 +3981,18 @@ gmp_popcount_limb (mp_limb_t x)
3990 unsigned c; 3981 unsigned c;
3991 3982
3992 /* Do 16 bits at a time, to avoid limb-sized constants. */ 3983 /* Do 16 bits at a time, to avoid limb-sized constants. */
3993 for (c = 0; x > 0; x >>= 16) 3984 int LOCAL_SHIFT_BITS = 16;
3985 for (c = 0; x > 0;)
3994 { 3986 {
3995 unsigned w = x - ((x >> 1) & 0x5555); 3987 unsigned w = x - ((x >> 1) & 0x5555);
3996 w = ((w >> 2) & 0x3333) + (w & 0x3333); 3988 w = ((w >> 2) & 0x3333) + (w & 0x3333);
3997 w = (w >> 4) + w; 3989 w = (w >> 4) + w;
3998 w = ((w >> 8) & 0x000f) + (w & 0x000f); 3990 w = ((w >> 8) & 0x000f) + (w & 0x000f);
3999 c += w; 3991 c += w;
3992 if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS)
3993 x >>= LOCAL_SHIFT_BITS;
3994 else
3995 x = 0;
4000 } 3996 }
4001 return c; 3997 return c;
4002} 3998}
@@ -4492,7 +4488,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4492 ptrdiff_t word_step; 4488 ptrdiff_t word_step;
4493 /* The current (partial) limb. */ 4489 /* The current (partial) limb. */
4494 mp_limb_t limb; 4490 mp_limb_t limb;
4495 /* The number of bytes left to do in this limb. */ 4491 /* The number of bytes left to to in this limb. */
4496 size_t bytes; 4492 size_t bytes;
4497 /* The index where the limb was read. */ 4493 /* The index where the limb was read. */
4498 mp_size_t i; 4494 mp_size_t i;
@@ -4503,10 +4499,15 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4503 limb = u->_mp_d[un-1]; 4499 limb = u->_mp_d[un-1];
4504 assert (limb != 0); 4500 assert (limb != 0);
4505 4501
4506 k = 0; 4502 k = (GMP_LIMB_BITS <= CHAR_BIT);
4507 do { 4503 if (!k)
4508 k++; limb >>= CHAR_BIT; 4504 {
4509 } while (limb != 0); 4505 do {
4506 int LOCAL_CHAR_BIT = CHAR_BIT;
4507 k++; limb >>= LOCAL_CHAR_BIT;
4508 } while (limb != 0);
4509 }
4510 /* else limb = 0; */
4510 4511
4511 count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; 4512 count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
4512 4513
@@ -4535,17 +4536,28 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4535 for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) 4536 for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
4536 { 4537 {
4537 size_t j; 4538 size_t j;
4538 for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) 4539 for (j = 0; j < size; ++j, p -= (ptrdiff_t) endian)
4539 { 4540 {
4540 if (bytes == 0) 4541 if (sizeof (mp_limb_t) == 1)
4541 { 4542 {
4542 if (i < un) 4543 if (i < un)
4543 limb = u->_mp_d[i++]; 4544 *p = u->_mp_d[i++];
4544 bytes = sizeof (mp_limb_t); 4545 else
4546 *p = 0;
4547 }
4548 else
4549 {
4550 int LOCAL_CHAR_BIT = CHAR_BIT;
4551 if (bytes == 0)
4552 {
4553 if (i < un)
4554 limb = u->_mp_d[i++];
4555 bytes = sizeof (mp_limb_t);
4556 }
4557 *p = limb;
4558 limb >>= LOCAL_CHAR_BIT;
4559 bytes--;
4545 } 4560 }
4546 *p = limb;
4547 limb >>= CHAR_BIT;
4548 bytes--;
4549 } 4561 }
4550 } 4562 }
4551 assert (i == un); 4563 assert (i == un);
diff --git a/src/mini-gmp.h b/src/mini-gmp.h
index 27e0c0671a2..7cce3f7a328 100644
--- a/src/mini-gmp.h
+++ b/src/mini-gmp.h
@@ -1,6 +1,6 @@
1/* mini-gmp, a minimalistic implementation of a GNU GMP subset. 1/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
2 2
3Copyright 2011-2015, 2017 Free Software Foundation, Inc. 3Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc.
4 4
5This file is part of the GNU MP Library. 5This file is part of the GNU MP Library.
6 6
@@ -53,7 +53,11 @@ void mp_get_memory_functions (void *(**) (size_t),
53 void *(**) (void *, size_t, size_t), 53 void *(**) (void *, size_t, size_t),
54 void (**) (void *, size_t)); 54 void (**) (void *, size_t));
55 55
56typedef unsigned long mp_limb_t; 56#ifndef MINI_GMP_LIMB_TYPE
57#define MINI_GMP_LIMB_TYPE long
58#endif
59
60typedef unsigned MINI_GMP_LIMB_TYPE mp_limb_t;
57typedef long mp_size_t; 61typedef long mp_size_t;
58typedef unsigned long mp_bitcnt_t; 62typedef unsigned long mp_bitcnt_t;
59 63