aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorAndy Moreton2018-08-04 10:28:13 -0600
committerTom Tromey2018-08-04 10:28:13 -0600
commitbc8ff54efee05f4a2769be32046866ed1e152b41 (patch)
treec6dac43f3b9abfc6bde54a9d245c04e5dbb360d5 /src/data.c
parent76715f8921dca740880cd22c644a6328cd810846 (diff)
downloademacs-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/data.c')
-rw-r--r--src/data.c96
1 files changed, 79 insertions, 17 deletions
diff --git a/src/data.c b/src/data.c
index 0deebdca1ae..3d55d9d17d5 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2409,7 +2409,18 @@ bignumcompare (Lisp_Object num1, Lisp_Object num2,
2409 if (FLOATP (num2)) 2409 if (FLOATP (num2))
2410 cmp = mpz_cmp_d (XBIGNUM (num1)->value, XFLOAT_DATA (num2)); 2410 cmp = mpz_cmp_d (XBIGNUM (num1)->value, XFLOAT_DATA (num2));
2411 else if (FIXNUMP (num2)) 2411 else if (FIXNUMP (num2))
2412 cmp = mpz_cmp_si (XBIGNUM (num1)->value, XINT (num2)); 2412 {
2413 if (sizeof (EMACS_INT) > sizeof (long) && XINT (num2) > LONG_MAX)
2414 {
2415 mpz_t tem;
2416 mpz_init (tem);
2417 mpz_set_intmax (tem, XINT (num2));
2418 cmp = mpz_cmp (XBIGNUM (num1)->value, tem);
2419 mpz_clear (tem);
2420 }
2421 else
2422 cmp = mpz_cmp_si (XBIGNUM (num1)->value, XINT (num2));
2423 }
2413 else 2424 else
2414 { 2425 {
2415 eassume (BIGNUMP (num2)); 2426 eassume (BIGNUMP (num2));
@@ -2422,10 +2433,19 @@ bignumcompare (Lisp_Object num1, Lisp_Object num2,
2422 if (FLOATP (num1)) 2433 if (FLOATP (num1))
2423 cmp = - mpz_cmp_d (XBIGNUM (num2)->value, XFLOAT_DATA (num1)); 2434 cmp = - mpz_cmp_d (XBIGNUM (num2)->value, XFLOAT_DATA (num1));
2424 else 2435 else
2425 { 2436 {
2426 eassume (FIXNUMP (num1)); 2437 eassume (FIXNUMP (num1));
2427 cmp = - mpz_cmp_si (XBIGNUM (num2)->value, XINT (num1)); 2438 if (sizeof (EMACS_INT) > sizeof (long) && XINT (num1) > LONG_MAX)
2428 } 2439 {
2440 mpz_t tem;
2441 mpz_init (tem);
2442 mpz_set_intmax (tem, XINT (num1));
2443 cmp = - mpz_cmp (XBIGNUM (num2)->value, tem);
2444 mpz_clear (tem);
2445 }
2446 else
2447 cmp = - mpz_cmp_si (XBIGNUM (num2)->value, XINT (num1));
2448 }
2429 } 2449 }
2430 2450
2431 switch (comparison) 2451 switch (comparison)
@@ -2860,7 +2880,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2860 { 2880 {
2861 /* Using args[argnum] as argument to CHECK_NUMBER... */ 2881 /* Using args[argnum] as argument to CHECK_NUMBER... */
2862 val = args[argnum]; 2882 val = args[argnum];
2863 CHECK_NUMBER (val); 2883 CHECK_NUMBER_COERCE_MARKER (val);
2864 2884
2865 if (FLOATP (val)) 2885 if (FLOATP (val))
2866 return unbind_to (count, 2886 return unbind_to (count,
@@ -2871,7 +2891,15 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2871 case Aadd: 2891 case Aadd:
2872 if (BIGNUMP (val)) 2892 if (BIGNUMP (val))
2873 mpz_add (accum, accum, XBIGNUM (val)->value); 2893 mpz_add (accum, accum, XBIGNUM (val)->value);
2874 else if (XINT (val) < 0) 2894 else if (sizeof (EMACS_INT) > sizeof (long))
2895 {
2896 mpz_t tem;
2897 mpz_init (tem);
2898 mpz_set_intmax (tem, XINT (val));
2899 mpz_add (accum, accum, tem);
2900 mpz_clear (tem);
2901 }
2902 else if (XINT (val) < 0)
2875 mpz_sub_ui (accum, accum, - XINT (val)); 2903 mpz_sub_ui (accum, accum, - XINT (val));
2876 else 2904 else
2877 mpz_add_ui (accum, accum, XINT (val)); 2905 mpz_add_ui (accum, accum, XINT (val));
@@ -2888,6 +2916,14 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2888 } 2916 }
2889 else if (BIGNUMP (val)) 2917 else if (BIGNUMP (val))
2890 mpz_sub (accum, accum, XBIGNUM (val)->value); 2918 mpz_sub (accum, accum, XBIGNUM (val)->value);
2919 else if (sizeof (EMACS_INT) > sizeof (long))
2920 {
2921 mpz_t tem;
2922 mpz_init (tem);
2923 mpz_set_intmax (tem, XINT (val));
2924 mpz_sub (accum, accum, tem);
2925 mpz_clear (tem);
2926 }
2891 else if (XINT (val) < 0) 2927 else if (XINT (val) < 0)
2892 mpz_add_ui (accum, accum, - XINT (val)); 2928 mpz_add_ui (accum, accum, - XINT (val));
2893 else 2929 else
@@ -2896,6 +2932,14 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2896 case Amult: 2932 case Amult:
2897 if (BIGNUMP (val)) 2933 if (BIGNUMP (val))
2898 mpz_mul (accum, accum, XBIGNUM (val)->value); 2934 mpz_mul (accum, accum, XBIGNUM (val)->value);
2935 else if (sizeof (EMACS_INT) > sizeof (long))
2936 {
2937 mpz_t tem;
2938 mpz_init (tem);
2939 mpz_set_intmax (tem, XINT (val));
2940 mpz_mul (accum, accum, tem);
2941 mpz_clear (tem);
2942 }
2899 else 2943 else
2900 mpz_mul_si (accum, accum, XINT (val)); 2944 mpz_mul_si (accum, accum, XINT (val));
2901 break; 2945 break;
@@ -2915,6 +2959,14 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2915 xsignal0 (Qarith_error); 2959 xsignal0 (Qarith_error);
2916 if (BIGNUMP (val)) 2960 if (BIGNUMP (val))
2917 mpz_tdiv_q (accum, accum, XBIGNUM (val)->value); 2961 mpz_tdiv_q (accum, accum, XBIGNUM (val)->value);
2962 else if (sizeof (EMACS_INT) > sizeof (long))
2963 {
2964 mpz_t tem;
2965 mpz_init (tem);
2966 mpz_set_intmax (tem, XINT (val));
2967 mpz_tdiv_q (accum, accum, tem);
2968 mpz_clear (tem);
2969 }
2918 else 2970 else
2919 { 2971 {
2920 EMACS_INT value = XINT (val); 2972 EMACS_INT value = XINT (val);
@@ -2982,8 +3034,9 @@ float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code,
2982 3034
2983 for (; argnum < nargs; argnum++) 3035 for (; argnum < nargs; argnum++)
2984 { 3036 {
2985 val = args[argnum]; /* using args[argnum] as argument to CHECK_FIXNUM_... */ 3037 /* using args[argnum] as argument to CHECK_NUMBER_... */
2986 CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER (val); 3038 val = args[argnum];
3039 CHECK_NUMBER_COERCE_MARKER (val);
2987 3040
2988 if (FLOATP (val)) 3041 if (FLOATP (val))
2989 { 3042 {
@@ -3277,7 +3330,7 @@ representation. */)
3277 3330
3278 if (BIGNUMP (value)) 3331 if (BIGNUMP (value))
3279 { 3332 {
3280 if (mpz_cmp_si (XBIGNUM (value)->value, 0) >= 0) 3333 if (mpz_sgn (XBIGNUM (value)->value) >= 0)
3281 return make_fixnum (mpz_popcount (XBIGNUM (value)->value)); 3334 return make_fixnum (mpz_popcount (XBIGNUM (value)->value));
3282 mpz_t tem; 3335 mpz_t tem;
3283 mpz_init (tem); 3336 mpz_init (tem);
@@ -3314,8 +3367,10 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
3314 mpz_init (result); 3367 mpz_init (result);
3315 if (XINT (count) >= 0) 3368 if (XINT (count) >= 0)
3316 mpz_mul_2exp (result, XBIGNUM (value)->value, XINT (count)); 3369 mpz_mul_2exp (result, XBIGNUM (value)->value, XINT (count));
3317 else 3370 else if (lsh)
3318 mpz_tdiv_q_2exp (result, XBIGNUM (value)->value, - XINT (count)); 3371 mpz_tdiv_q_2exp (result, XBIGNUM (value)->value, - XINT (count));
3372 else
3373 mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XINT (count));
3319 val = make_number (result); 3374 val = make_number (result);
3320 mpz_clear (result); 3375 mpz_clear (result);
3321 } 3376 }
@@ -3325,14 +3380,21 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
3325 mpz_t result; 3380 mpz_t result;
3326 eassume (FIXNUMP (value)); 3381 eassume (FIXNUMP (value));
3327 mpz_init (result); 3382 mpz_init (result);
3328 if (lsh) 3383
3329 mpz_set_uintmax (result, XUINT (value)); 3384 mpz_set_intmax (result, XINT (value));
3330 else 3385
3331 mpz_set_intmax (result, XINT (value));
3332 if (XINT (count) >= 0) 3386 if (XINT (count) >= 0)
3333 mpz_mul_2exp (result, result, XINT (count)); 3387 mpz_mul_2exp (result, result, XINT (count));
3334 else 3388 else if (lsh)
3335 mpz_tdiv_q_2exp (result, result, - XINT (count)); 3389 {
3390 if (mpz_sgn (result) > 0)
3391 mpz_fdiv_q_2exp (result, result, - XINT (count));
3392 else
3393 mpz_fdiv_q_2exp (result, result, - XINT (count));
3394 }
3395 else /* ash */
3396 mpz_fdiv_q_2exp (result, result, - XINT (count));
3397
3336 val = make_number (result); 3398 val = make_number (result);
3337 mpz_clear (result); 3399 mpz_clear (result);
3338 } 3400 }
@@ -3414,7 +3476,7 @@ Markers are converted to integers. */)
3414 else 3476 else
3415 { 3477 {
3416 eassume (FIXNUMP (number)); 3478 eassume (FIXNUMP (number));
3417 if (XINT (number) > MOST_POSITIVE_FIXNUM) 3479 if (XINT (number) > MOST_NEGATIVE_FIXNUM)
3418 XSETINT (number, XINT (number) - 1); 3480 XSETINT (number, XINT (number) - 1);
3419 else 3481 else
3420 { 3482 {