diff options
| author | Paul Eggert | 2020-01-26 12:52:56 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-01-26 12:54:47 -0800 |
| commit | 901f58ce5f4603e14f4cd1bb64d4d5cf06985b89 (patch) | |
| tree | a989ee9fde6d9d09e4682fd754f70ed1e2d77fae /src | |
| parent | 491c909175eb9ff99ff3fdf766e81b333b9d316a (diff) | |
| download | emacs-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
Diffstat (limited to 'src')
| -rw-r--r-- | src/mini-gmp.c | 222 | ||||
| -rw-r--r-- | src/mini-gmp.h | 8 |
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) | |||
| 768 | mp_limb_t | 770 | mp_limb_t |
| 769 | mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) | 771 | mpn_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 | ||
| 887 | struct gmp_div_inverse | 878 | struct 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 | ||
| 3 | Copyright 2011-2015, 2017 Free Software Foundation, Inc. | 3 | Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of the GNU MP Library. | 5 | This 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 | ||
| 56 | typedef unsigned long mp_limb_t; | 56 | #ifndef MINI_GMP_LIMB_TYPE |
| 57 | #define MINI_GMP_LIMB_TYPE long | ||
| 58 | #endif | ||
| 59 | |||
| 60 | typedef unsigned MINI_GMP_LIMB_TYPE mp_limb_t; | ||
| 57 | typedef long mp_size_t; | 61 | typedef long mp_size_t; |
| 58 | typedef unsigned long mp_bitcnt_t; | 62 | typedef unsigned long mp_bitcnt_t; |
| 59 | 63 | ||