diff options
| author | Andy Moreton | 2018-08-04 10:28:13 -0600 |
|---|---|---|
| committer | Tom Tromey | 2018-08-04 10:28:13 -0600 |
| commit | bc8ff54efee05f4a2769be32046866ed1e152b41 (patch) | |
| tree | c6dac43f3b9abfc6bde54a9d245c04e5dbb360d5 /src/alloc.c | |
| parent | 76715f8921dca740880cd22c644a6328cd810846 (diff) | |
| download | emacs-bc8ff54efee05f4a2769be32046866ed1e152b41.tar.gz emacs-bc8ff54efee05f4a2769be32046866ed1e152b41.zip | |
Make bignums work better when EMACS_INT is larger than long
* lisp/international/ccl.el (ccl-fixnum): New function.
(ccl-embed-data, ccl-embed-current-address, ccl-dump): Use it.
* src/alloc.c (make_number): Handle case where EMACS_INT is
larger than long.
* src/data.c (bignumcompare): Handle case where EMACS_INT is
larger than long.
(arith_driver): Likewise. Coerce markers.
(float_arith_driver): Coerce markers.
(Flogcount): Use mpz_sgn.
(ash_lsh_impl): Fix bugs.
(Fsub1): Fix underflow check.
* src/lisp.h (NUMBERP): Don't check BIGNUMP.
(CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER): Fix indentation.
* test/lisp/international/ccl-tests.el: New file.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/alloc.c b/src/alloc.c index 1dc1bbb031a..367bb73fc15 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3815,6 +3815,34 @@ make_number (mpz_t value) | |||
| 3815 | } | 3815 | } |
| 3816 | } | 3816 | } |
| 3817 | 3817 | ||
| 3818 | /* Check if fixnum can be larger than long. */ | ||
| 3819 | if (sizeof (EMACS_INT) > sizeof (long)) | ||
| 3820 | { | ||
| 3821 | size_t bits = mpz_sizeinbase (value, 2); | ||
| 3822 | int sign = mpz_sgn (value); | ||
| 3823 | |||
| 3824 | if (bits < FIXNUM_BITS + (sign < 0)) | ||
| 3825 | { | ||
| 3826 | EMACS_INT v = 0; | ||
| 3827 | size_t limbs = mpz_size (value); | ||
| 3828 | mp_size_t i; | ||
| 3829 | |||
| 3830 | for (i = 0; i < limbs; i++) | ||
| 3831 | { | ||
| 3832 | mp_limb_t limb = mpz_getlimbn (value, i); | ||
| 3833 | v |= (EMACS_INT) ((EMACS_UINT) limb << (i * GMP_NUMB_BITS)); | ||
| 3834 | } | ||
| 3835 | if (sign < 0) | ||
| 3836 | v = -v; | ||
| 3837 | |||
| 3838 | if (!FIXNUM_OVERFLOW_P (v)) | ||
| 3839 | { | ||
| 3840 | XSETINT (obj, v); | ||
| 3841 | return obj; | ||
| 3842 | } | ||
| 3843 | } | ||
| 3844 | } | ||
| 3845 | |||
| 3818 | obj = allocate_misc (Lisp_Misc_Bignum); | 3846 | obj = allocate_misc (Lisp_Misc_Bignum); |
| 3819 | b = XBIGNUM (obj); | 3847 | b = XBIGNUM (obj); |
| 3820 | /* We could mpz_init + mpz_swap here, to avoid a copy, but the | 3848 | /* We could mpz_init + mpz_swap here, to avoid a copy, but the |