aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorTom Tromey2018-08-11 13:34:17 -0600
committerTom Tromey2018-08-11 13:34:17 -0600
commit78ec68e18f07a90a9ad400683b973ff51baa80e1 (patch)
tree638c986bf753e3ddab9992ba1ef0a10a3d4891f0 /src/data.c
parentba1c4f63e3d2adbe9b590a3c51c2a0808c84723f (diff)
parent79f59d41a3d2ef3b4a9a87265bf517206a5837ad (diff)
downloademacs-78ec68e18f07a90a9ad400683b973ff51baa80e1.tar.gz
emacs-78ec68e18f07a90a9ad400683b973ff51baa80e1.zip
Merge branch 'feature/bignum'
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c693
1 files changed, 554 insertions, 139 deletions
diff --git a/src/data.c b/src/data.c
index aaccb675183..7d701fde0e2 100644
--- a/src/data.c
+++ b/src/data.c
@@ -74,7 +74,7 @@ XKBOARD_OBJFWD (union Lisp_Fwd *a)
74 return &a->u_kboard_objfwd; 74 return &a->u_kboard_objfwd;
75} 75}
76static struct Lisp_Intfwd * 76static struct Lisp_Intfwd *
77XINTFWD (union Lisp_Fwd *a) 77XFIXNUMFWD (union Lisp_Fwd *a)
78{ 78{
79 eassert (INTFWDP (a)); 79 eassert (INTFWDP (a));
80 return &a->u_intfwd; 80 return &a->u_intfwd;
@@ -132,13 +132,13 @@ set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
132static _Noreturn void 132static _Noreturn void
133wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3) 133wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
134{ 134{
135 Lisp_Object size1 = make_number (bool_vector_size (a1)); 135 Lisp_Object size1 = make_fixnum (bool_vector_size (a1));
136 Lisp_Object size2 = make_number (bool_vector_size (a2)); 136 Lisp_Object size2 = make_fixnum (bool_vector_size (a2));
137 if (NILP (a3)) 137 if (NILP (a3))
138 xsignal2 (Qwrong_length_argument, size1, size2); 138 xsignal2 (Qwrong_length_argument, size1, size2);
139 else 139 else
140 xsignal3 (Qwrong_length_argument, size1, size2, 140 xsignal3 (Qwrong_length_argument, size1, size2,
141 make_number (bool_vector_size (a3))); 141 make_fixnum (bool_vector_size (a3)));
142} 142}
143 143
144_Noreturn void 144_Noreturn void
@@ -234,6 +234,8 @@ for example, (type-of 1) returns `integer'. */)
234 case Lisp_Misc_User_Ptr: 234 case Lisp_Misc_User_Ptr:
235 return Quser_ptr; 235 return Quser_ptr;
236#endif 236#endif
237 case Lisp_Misc_Bignum:
238 return Qinteger;
237 default: 239 default:
238 emacs_abort (); 240 emacs_abort ();
239 } 241 }
@@ -520,6 +522,16 @@ DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0,
520 return Qnil; 522 return Qnil;
521} 523}
522 524
525DEFUN ("fixnump", Ffixnump, Sfixnump, 1, 1, 0,
526 doc: /* Return t if OBJECT is an fixnum. */
527 attributes: const)
528 (Lisp_Object object)
529{
530 if (FIXNUMP (object))
531 return Qt;
532 return Qnil;
533}
534
523DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0, 535DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0,
524 doc: /* Return t if OBJECT is an integer or a marker (editor pointer). */) 536 doc: /* Return t if OBJECT is an integer or a marker (editor pointer). */)
525 (register Lisp_Object object) 537 (register Lisp_Object object)
@@ -597,6 +609,15 @@ DEFUN ("condition-variable-p", Fcondition_variable_p, Scondition_variable_p,
597 return Qt; 609 return Qt;
598 return Qnil; 610 return Qnil;
599} 611}
612
613DEFUN ("bignump", Fbignump, Sbignump, 1, 1, 0,
614 doc: /* Return t if OBJECT is a bignum. */)
615 (Lisp_Object object)
616{
617 if (BIGNUMP (object))
618 return Qt;
619 return Qnil;
620}
600 621
601/* Extract and set components of lists. */ 622/* Extract and set components of lists. */
602 623
@@ -858,10 +879,10 @@ function with `&rest' args, or `unevalled' for a special form. */)
858 CHECK_SUBR (subr); 879 CHECK_SUBR (subr);
859 minargs = XSUBR (subr)->min_args; 880 minargs = XSUBR (subr)->min_args;
860 maxargs = XSUBR (subr)->max_args; 881 maxargs = XSUBR (subr)->max_args;
861 return Fcons (make_number (minargs), 882 return Fcons (make_fixnum (minargs),
862 maxargs == MANY ? Qmany 883 maxargs == MANY ? Qmany
863 : maxargs == UNEVALLED ? Qunevalled 884 : maxargs == UNEVALLED ? Qunevalled
864 : make_number (maxargs)); 885 : make_fixnum (maxargs));
865} 886}
866 887
867DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, 888DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
@@ -992,7 +1013,7 @@ do_symval_forwarding (register union Lisp_Fwd *valcontents)
992 switch (XFWDTYPE (valcontents)) 1013 switch (XFWDTYPE (valcontents))
993 { 1014 {
994 case Lisp_Fwd_Int: 1015 case Lisp_Fwd_Int:
995 XSETINT (val, *XINTFWD (valcontents)->intvar); 1016 XSETINT (val, *XFIXNUMFWD (valcontents)->intvar);
996 return val; 1017 return val;
997 1018
998 case Lisp_Fwd_Bool: 1019 case Lisp_Fwd_Bool:
@@ -1029,7 +1050,7 @@ do_symval_forwarding (register union Lisp_Fwd *valcontents)
1029void 1050void
1030wrong_choice (Lisp_Object choice, Lisp_Object wrong) 1051wrong_choice (Lisp_Object choice, Lisp_Object wrong)
1031{ 1052{
1032 ptrdiff_t i = 0, len = XINT (Flength (choice)); 1053 ptrdiff_t i = 0, len = XFIXNUM (Flength (choice));
1033 Lisp_Object obj, *args; 1054 Lisp_Object obj, *args;
1034 AUTO_STRING (one_of, "One of "); 1055 AUTO_STRING (one_of, "One of ");
1035 AUTO_STRING (comma, ", "); 1056 AUTO_STRING (comma, ", ");
@@ -1084,8 +1105,8 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
1084 switch (XFWDTYPE (valcontents)) 1105 switch (XFWDTYPE (valcontents))
1085 { 1106 {
1086 case Lisp_Fwd_Int: 1107 case Lisp_Fwd_Int:
1087 CHECK_NUMBER (newval); 1108 CHECK_FIXNUM (newval);
1088 *XINTFWD (valcontents)->intvar = XINT (newval); 1109 *XFIXNUMFWD (valcontents)->intvar = XFIXNUM (newval);
1089 break; 1110 break;
1090 1111
1091 case Lisp_Fwd_Bool: 1112 case Lisp_Fwd_Bool:
@@ -1140,7 +1161,7 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
1140 else if ((prop = Fget (predicate, Qrange), !NILP (prop))) 1161 else if ((prop = Fget (predicate, Qrange), !NILP (prop)))
1141 { 1162 {
1142 Lisp_Object min = XCAR (prop), max = XCDR (prop); 1163 Lisp_Object min = XCAR (prop), max = XCDR (prop);
1143 if (! NUMBERP (newval) 1164 if (! FIXED_OR_FLOATP (newval)
1144 || NILP (CALLN (Fleq, min, newval, max))) 1165 || NILP (CALLN (Fleq, min, newval, max)))
1145 wrong_range (min, max, newval); 1166 wrong_range (min, max, newval);
1146 } 1167 }
@@ -2232,8 +2253,8 @@ or a byte-code object. IDX starts at 0. */)
2232{ 2253{
2233 register EMACS_INT idxval; 2254 register EMACS_INT idxval;
2234 2255
2235 CHECK_NUMBER (idx); 2256 CHECK_FIXNUM (idx);
2236 idxval = XINT (idx); 2257 idxval = XFIXNUM (idx);
2237 if (STRINGP (array)) 2258 if (STRINGP (array))
2238 { 2259 {
2239 int c; 2260 int c;
@@ -2242,11 +2263,11 @@ or a byte-code object. IDX starts at 0. */)
2242 if (idxval < 0 || idxval >= SCHARS (array)) 2263 if (idxval < 0 || idxval >= SCHARS (array))
2243 args_out_of_range (array, idx); 2264 args_out_of_range (array, idx);
2244 if (! STRING_MULTIBYTE (array)) 2265 if (! STRING_MULTIBYTE (array))
2245 return make_number ((unsigned char) SREF (array, idxval)); 2266 return make_fixnum ((unsigned char) SREF (array, idxval));
2246 idxval_byte = string_char_to_byte (array, idxval); 2267 idxval_byte = string_char_to_byte (array, idxval);
2247 2268
2248 c = STRING_CHAR (SDATA (array) + idxval_byte); 2269 c = STRING_CHAR (SDATA (array) + idxval_byte);
2249 return make_number (c); 2270 return make_fixnum (c);
2250 } 2271 }
2251 else if (BOOL_VECTOR_P (array)) 2272 else if (BOOL_VECTOR_P (array))
2252 { 2273 {
@@ -2283,8 +2304,8 @@ bool-vector. IDX starts at 0. */)
2283{ 2304{
2284 register EMACS_INT idxval; 2305 register EMACS_INT idxval;
2285 2306
2286 CHECK_NUMBER (idx); 2307 CHECK_FIXNUM (idx);
2287 idxval = XINT (idx); 2308 idxval = XFIXNUM (idx);
2288 if (! RECORDP (array)) 2309 if (! RECORDP (array))
2289 CHECK_ARRAY (array, Qarrayp); 2310 CHECK_ARRAY (array, Qarrayp);
2290 2311
@@ -2320,7 +2341,7 @@ bool-vector. IDX starts at 0. */)
2320 if (idxval < 0 || idxval >= SCHARS (array)) 2341 if (idxval < 0 || idxval >= SCHARS (array))
2321 args_out_of_range (array, idx); 2342 args_out_of_range (array, idx);
2322 CHECK_CHARACTER (newelt); 2343 CHECK_CHARACTER (newelt);
2323 c = XFASTINT (newelt); 2344 c = XFIXNAT (newelt);
2324 2345
2325 if (STRING_MULTIBYTE (array)) 2346 if (STRING_MULTIBYTE (array))
2326 { 2347 {
@@ -2376,6 +2397,106 @@ bool-vector. IDX starts at 0. */)
2376 2397
2377/* Arithmetic functions */ 2398/* Arithmetic functions */
2378 2399
2400#ifndef isnan
2401# define isnan(x) ((x) != (x))
2402#endif
2403
2404static Lisp_Object
2405bignumcompare (Lisp_Object num1, Lisp_Object num2,
2406 enum Arith_Comparison comparison)
2407{
2408 int cmp;
2409 bool test;
2410
2411 if (BIGNUMP (num1))
2412 {
2413 if (FLOATP (num2))
2414 {
2415 /* Note that GMP doesn't define comparisons against NaN, so
2416 we need to handle them specially. */
2417 if (isnan (XFLOAT_DATA (num2)))
2418 return Qnil;
2419 cmp = mpz_cmp_d (XBIGNUM (num1)->value, XFLOAT_DATA (num2));
2420 }
2421 else if (FIXNUMP (num2))
2422 {
2423 if (sizeof (EMACS_INT) > sizeof (long) && XFIXNUM (num2) > LONG_MAX)
2424 {
2425 mpz_t tem;
2426 mpz_init (tem);
2427 mpz_set_intmax (tem, XFIXNUM (num2));
2428 cmp = mpz_cmp (XBIGNUM (num1)->value, tem);
2429 mpz_clear (tem);
2430 }
2431 else
2432 cmp = mpz_cmp_si (XBIGNUM (num1)->value, XFIXNUM (num2));
2433 }
2434 else
2435 {
2436 eassume (BIGNUMP (num2));
2437 cmp = mpz_cmp (XBIGNUM (num1)->value, XBIGNUM (num2)->value);
2438 }
2439 }
2440 else
2441 {
2442 eassume (BIGNUMP (num2));
2443 if (FLOATP (num1))
2444 {
2445 /* Note that GMP doesn't define comparisons against NaN, so
2446 we need to handle them specially. */
2447 if (isnan (XFLOAT_DATA (num1)))
2448 return Qnil;
2449 cmp = - mpz_cmp_d (XBIGNUM (num2)->value, XFLOAT_DATA (num1));
2450 }
2451 else
2452 {
2453 eassume (FIXNUMP (num1));
2454 if (sizeof (EMACS_INT) > sizeof (long) && XFIXNUM (num1) > LONG_MAX)
2455 {
2456 mpz_t tem;
2457 mpz_init (tem);
2458 mpz_set_intmax (tem, XFIXNUM (num1));
2459 cmp = - mpz_cmp (XBIGNUM (num2)->value, tem);
2460 mpz_clear (tem);
2461 }
2462 else
2463 cmp = - mpz_cmp_si (XBIGNUM (num2)->value, XFIXNUM (num1));
2464 }
2465 }
2466
2467 switch (comparison)
2468 {
2469 case ARITH_EQUAL:
2470 test = cmp == 0;
2471 break;
2472
2473 case ARITH_NOTEQUAL:
2474 test = cmp != 0;
2475 break;
2476
2477 case ARITH_LESS:
2478 test = cmp < 0;
2479 break;
2480
2481 case ARITH_LESS_OR_EQUAL:
2482 test = cmp <= 0;
2483 break;
2484
2485 case ARITH_GRTR:
2486 test = cmp > 0;
2487 break;
2488
2489 case ARITH_GRTR_OR_EQUAL:
2490 test = cmp >= 0;
2491 break;
2492
2493 default:
2494 eassume (false);
2495 }
2496
2497 return test ? Qt : Qnil;
2498}
2499
2379Lisp_Object 2500Lisp_Object
2380arithcompare (Lisp_Object num1, Lisp_Object num2, 2501arithcompare (Lisp_Object num1, Lisp_Object num2,
2381 enum Arith_Comparison comparison) 2502 enum Arith_Comparison comparison)
@@ -2385,8 +2506,11 @@ arithcompare (Lisp_Object num1, Lisp_Object num2,
2385 bool fneq; 2506 bool fneq;
2386 bool test; 2507 bool test;
2387 2508
2388 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1); 2509 CHECK_NUMBER_COERCE_MARKER (num1);
2389 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2); 2510 CHECK_NUMBER_COERCE_MARKER (num2);
2511
2512 if (BIGNUMP (num1) || BIGNUMP (num2))
2513 return bignumcompare (num1, num2, comparison);
2390 2514
2391 /* If either arg is floating point, set F1 and F2 to the 'double' 2515 /* If either arg is floating point, set F1 and F2 to the 'double'
2392 approximations of the two arguments, and set FNEQ if floating-point 2516 approximations of the two arguments, and set FNEQ if floating-point
@@ -2413,13 +2537,13 @@ arithcompare (Lisp_Object num1, Lisp_Object num2,
2413 floating-point comparison reports a tie, NUM1 = F1 = F2 = I1 2537 floating-point comparison reports a tie, NUM1 = F1 = F2 = I1
2414 (exactly) so I1 - I2 = NUM1 - NUM2 (exactly), so comparing I1 2538 (exactly) so I1 - I2 = NUM1 - NUM2 (exactly), so comparing I1
2415 to I2 will break the tie correctly. */ 2539 to I2 will break the tie correctly. */
2416 i1 = f2 = i2 = XINT (num2); 2540 i1 = f2 = i2 = XFIXNUM (num2);
2417 } 2541 }
2418 fneq = f1 != f2; 2542 fneq = f1 != f2;
2419 } 2543 }
2420 else 2544 else
2421 { 2545 {
2422 i1 = XINT (num1); 2546 i1 = XFIXNUM (num1);
2423 if (FLOATP (num2)) 2547 if (FLOATP (num2))
2424 { 2548 {
2425 /* Compare an integer NUM1 to a float NUM2. This is the 2549 /* Compare an integer NUM1 to a float NUM2. This is the
@@ -2430,7 +2554,7 @@ arithcompare (Lisp_Object num1, Lisp_Object num2,
2430 } 2554 }
2431 else 2555 else
2432 { 2556 {
2433 i2 = XINT (num2); 2557 i2 = XFIXNUM (num2);
2434 fneq = false; 2558 fneq = false;
2435 } 2559 }
2436 } 2560 }
@@ -2532,12 +2656,12 @@ DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
2532 (eassert (FIXNUM_OVERFLOW_P (i)), \ 2656 (eassert (FIXNUM_OVERFLOW_P (i)), \
2533 (! (FIXNUM_OVERFLOW_P ((extremum) >> 16) \ 2657 (! (FIXNUM_OVERFLOW_P ((extremum) >> 16) \
2534 && FIXNUM_OVERFLOW_P ((i) >> 16)) \ 2658 && FIXNUM_OVERFLOW_P ((i) >> 16)) \
2535 ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ 2659 ? Fcons (make_fixnum ((i) >> 16), make_fixnum ((i) & 0xffff)) \
2536 : ! (FIXNUM_OVERFLOW_P ((extremum) >> 16 >> 24) \ 2660 : ! (FIXNUM_OVERFLOW_P ((extremum) >> 16 >> 24) \
2537 && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \ 2661 && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \
2538 ? Fcons (make_number ((i) >> 16 >> 24), \ 2662 ? Fcons (make_fixnum ((i) >> 16 >> 24), \
2539 Fcons (make_number ((i) >> 16 & 0xffffff), \ 2663 Fcons (make_fixnum ((i) >> 16 & 0xffffff), \
2540 make_number ((i) & 0xffff))) \ 2664 make_fixnum ((i) & 0xffff))) \
2541 : make_float (i))) 2665 : make_float (i)))
2542 2666
2543Lisp_Object 2667Lisp_Object
@@ -2561,10 +2685,10 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max)
2561{ 2685{
2562 bool valid = false; 2686 bool valid = false;
2563 uintmax_t val UNINIT; 2687 uintmax_t val UNINIT;
2564 if (INTEGERP (c)) 2688 if (FIXNUMP (c))
2565 { 2689 {
2566 valid = XINT (c) >= 0; 2690 valid = XFIXNUM (c) >= 0;
2567 val = XINT (c); 2691 val = XFIXNUM (c);
2568 } 2692 }
2569 else if (FLOATP (c)) 2693 else if (FLOATP (c))
2570 { 2694 {
@@ -2575,26 +2699,26 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max)
2575 valid = val == d; 2699 valid = val == d;
2576 } 2700 }
2577 } 2701 }
2578 else if (CONSP (c) && NATNUMP (XCAR (c))) 2702 else if (CONSP (c) && FIXNATP (XCAR (c)))
2579 { 2703 {
2580 uintmax_t top = XFASTINT (XCAR (c)); 2704 uintmax_t top = XFIXNAT (XCAR (c));
2581 Lisp_Object rest = XCDR (c); 2705 Lisp_Object rest = XCDR (c);
2582 if (top <= UINTMAX_MAX >> 24 >> 16 2706 if (top <= UINTMAX_MAX >> 24 >> 16
2583 && CONSP (rest) 2707 && CONSP (rest)
2584 && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 2708 && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24
2585 && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) 2709 && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16)
2586 { 2710 {
2587 uintmax_t mid = XFASTINT (XCAR (rest)); 2711 uintmax_t mid = XFIXNAT (XCAR (rest));
2588 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); 2712 val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest));
2589 valid = true; 2713 valid = true;
2590 } 2714 }
2591 else if (top <= UINTMAX_MAX >> 16) 2715 else if (top <= UINTMAX_MAX >> 16)
2592 { 2716 {
2593 if (CONSP (rest)) 2717 if (CONSP (rest))
2594 rest = XCAR (rest); 2718 rest = XCAR (rest);
2595 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) 2719 if (FIXNATP (rest) && XFIXNAT (rest) < 1 << 16)
2596 { 2720 {
2597 val = top << 16 | XFASTINT (rest); 2721 val = top << 16 | XFIXNAT (rest);
2598 valid = true; 2722 valid = true;
2599 } 2723 }
2600 } 2724 }
@@ -2615,9 +2739,9 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
2615{ 2739{
2616 bool valid = false; 2740 bool valid = false;
2617 intmax_t val UNINIT; 2741 intmax_t val UNINIT;
2618 if (INTEGERP (c)) 2742 if (FIXNUMP (c))
2619 { 2743 {
2620 val = XINT (c); 2744 val = XFIXNUM (c);
2621 valid = true; 2745 valid = true;
2622 } 2746 }
2623 else if (FLOATP (c)) 2747 else if (FLOATP (c))
@@ -2629,26 +2753,26 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
2629 valid = val == d; 2753 valid = val == d;
2630 } 2754 }
2631 } 2755 }
2632 else if (CONSP (c) && INTEGERP (XCAR (c))) 2756 else if (CONSP (c) && FIXNUMP (XCAR (c)))
2633 { 2757 {
2634 intmax_t top = XINT (XCAR (c)); 2758 intmax_t top = XFIXNUM (XCAR (c));
2635 Lisp_Object rest = XCDR (c); 2759 Lisp_Object rest = XCDR (c);
2636 if (top >= INTMAX_MIN >> 24 >> 16 && top <= INTMAX_MAX >> 24 >> 16 2760 if (top >= INTMAX_MIN >> 24 >> 16 && top <= INTMAX_MAX >> 24 >> 16
2637 && CONSP (rest) 2761 && CONSP (rest)
2638 && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 2762 && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24
2639 && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) 2763 && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16)
2640 { 2764 {
2641 intmax_t mid = XFASTINT (XCAR (rest)); 2765 intmax_t mid = XFIXNAT (XCAR (rest));
2642 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); 2766 val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest));
2643 valid = true; 2767 valid = true;
2644 } 2768 }
2645 else if (top >= INTMAX_MIN >> 16 && top <= INTMAX_MAX >> 16) 2769 else if (top >= INTMAX_MIN >> 16 && top <= INTMAX_MAX >> 16)
2646 { 2770 {
2647 if (CONSP (rest)) 2771 if (CONSP (rest))
2648 rest = XCAR (rest); 2772 rest = XCAR (rest);
2649 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) 2773 if (FIXNATP (rest) && XFIXNAT (rest) < 1 << 16)
2650 { 2774 {
2651 val = top << 16 | XFASTINT (rest); 2775 val = top << 16 | XFIXNAT (rest);
2652 valid = true; 2776 valid = true;
2653 } 2777 }
2654 } 2778 }
@@ -2668,12 +2792,20 @@ NUMBER may be an integer or a floating point number. */)
2668 char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; 2792 char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))];
2669 int len; 2793 int len;
2670 2794
2671 CHECK_NUMBER_OR_FLOAT (number); 2795 if (BIGNUMP (number))
2796 {
2797 ptrdiff_t count = SPECPDL_INDEX ();
2798 char *str = mpz_get_str (NULL, 10, XBIGNUM (number)->value);
2799 record_unwind_protect_ptr (xfree, str);
2800 return unbind_to (count, make_unibyte_string (str, strlen (str)));
2801 }
2802
2803 CHECK_FIXNUM_OR_FLOAT (number);
2672 2804
2673 if (FLOATP (number)) 2805 if (FLOATP (number))
2674 len = float_to_string (buffer, XFLOAT_DATA (number)); 2806 len = float_to_string (buffer, XFLOAT_DATA (number));
2675 else 2807 else
2676 len = sprintf (buffer, "%"pI"d", XINT (number)); 2808 len = sprintf (buffer, "%"pI"d", XFIXNUM (number));
2677 2809
2678 return make_unibyte_string (buffer, len); 2810 return make_unibyte_string (buffer, len);
2679} 2811}
@@ -2696,19 +2828,18 @@ If the base used is not 10, STRING is always parsed as an integer. */)
2696 b = 10; 2828 b = 10;
2697 else 2829 else
2698 { 2830 {
2699 CHECK_NUMBER (base); 2831 CHECK_FIXNUM (base);
2700 if (! (XINT (base) >= 2 && XINT (base) <= 16)) 2832 if (! (XFIXNUM (base) >= 2 && XFIXNUM (base) <= 16))
2701 xsignal1 (Qargs_out_of_range, base); 2833 xsignal1 (Qargs_out_of_range, base);
2702 b = XINT (base); 2834 b = XFIXNUM (base);
2703 } 2835 }
2704 2836
2705 char *p = SSDATA (string); 2837 char *p = SSDATA (string);
2706 while (*p == ' ' || *p == '\t') 2838 while (*p == ' ' || *p == '\t')
2707 p++; 2839 p++;
2708 2840
2709 int flags = S2N_IGNORE_TRAILING | S2N_OVERFLOW_TO_FLOAT; 2841 Lisp_Object val = string_to_number (p, b, S2N_IGNORE_TRAILING);
2710 Lisp_Object val = string_to_number (p, b, flags); 2842 return NILP (val) ? make_fixnum (0) : val;
2711 return NILP (val) ? make_number (0) : val;
2712} 2843}
2713 2844
2714enum arithop 2845enum arithop
@@ -2722,16 +2853,25 @@ enum arithop
2722 Alogxor 2853 Alogxor
2723 }; 2854 };
2724 2855
2856static void
2857free_mpz_value (void *value_ptr)
2858{
2859 mpz_clear (*(mpz_t *) value_ptr);
2860}
2861
2725static Lisp_Object float_arith_driver (double, ptrdiff_t, enum arithop, 2862static Lisp_Object float_arith_driver (double, ptrdiff_t, enum arithop,
2726 ptrdiff_t, Lisp_Object *); 2863 ptrdiff_t, Lisp_Object *);
2864
2727static Lisp_Object 2865static Lisp_Object
2728arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) 2866arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2729{ 2867{
2730 Lisp_Object val; 2868 Lisp_Object val = Qnil;
2731 ptrdiff_t argnum, ok_args; 2869 ptrdiff_t argnum;
2732 EMACS_INT accum = 0; 2870 ptrdiff_t count = SPECPDL_INDEX ();
2733 EMACS_INT next, ok_accum; 2871 mpz_t accum;
2734 bool overflow = 0; 2872
2873 mpz_init (accum);
2874 record_unwind_protect_ptr (free_mpz_value, &accum);
2735 2875
2736 switch (code) 2876 switch (code)
2737 { 2877 {
@@ -2739,14 +2879,14 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2739 case Alogxor: 2879 case Alogxor:
2740 case Aadd: 2880 case Aadd:
2741 case Asub: 2881 case Asub:
2742 accum = 0; 2882 /* ACCUM is already 0. */
2743 break; 2883 break;
2744 case Amult: 2884 case Amult:
2745 case Adiv: 2885 case Adiv:
2746 accum = 1; 2886 mpz_set_si (accum, 1);
2747 break; 2887 break;
2748 case Alogand: 2888 case Alogand:
2749 accum = -1; 2889 mpz_set_si (accum, -1);
2750 break; 2890 break;
2751 default: 2891 default:
2752 break; 2892 break;
@@ -2754,62 +2894,147 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
2754 2894
2755 for (argnum = 0; argnum < nargs; argnum++) 2895 for (argnum = 0; argnum < nargs; argnum++)
2756 { 2896 {
2757 if (! overflow) 2897 /* Using args[argnum] as argument to CHECK_NUMBER... */
2758 {
2759 ok_args = argnum;
2760 ok_accum = accum;
2761 }
2762
2763 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2764 val = args[argnum]; 2898 val = args[argnum];
2765 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2899 CHECK_NUMBER_COERCE_MARKER (val);
2766 2900
2767 if (FLOATP (val)) 2901 if (FLOATP (val))
2768 return float_arith_driver (ok_accum, ok_args, code, 2902 return unbind_to (count,
2769 nargs, args); 2903 float_arith_driver (mpz_get_d (accum), argnum, code,
2770 args[argnum] = val; 2904 nargs, args));
2771 next = XINT (args[argnum]);
2772 switch (code) 2905 switch (code)
2773 { 2906 {
2774 case Aadd: 2907 case Aadd:
2775 overflow |= INT_ADD_WRAPV (accum, next, &accum); 2908 if (BIGNUMP (val))
2909 mpz_add (accum, accum, XBIGNUM (val)->value);
2910 else if (sizeof (EMACS_INT) > sizeof (long))
2911 {
2912 mpz_t tem;
2913 mpz_init (tem);
2914 mpz_set_intmax (tem, XFIXNUM (val));
2915 mpz_add (accum, accum, tem);
2916 mpz_clear (tem);
2917 }
2918 else if (XFIXNUM (val) < 0)
2919 mpz_sub_ui (accum, accum, - XFIXNUM (val));
2920 else
2921 mpz_add_ui (accum, accum, XFIXNUM (val));
2776 break; 2922 break;
2777 case Asub: 2923 case Asub:
2778 if (! argnum) 2924 if (! argnum)
2779 accum = nargs == 1 ? - next : next; 2925 {
2926 if (BIGNUMP (val))
2927 mpz_set (accum, XBIGNUM (val)->value);
2928 else
2929 mpz_set_intmax (accum, XFIXNUM (val));
2930 if (nargs == 1)
2931 mpz_neg (accum, accum);
2932 }
2933 else if (BIGNUMP (val))
2934 mpz_sub (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, XFIXNUM (val));
2940 mpz_sub (accum, accum, tem);
2941 mpz_clear (tem);
2942 }
2943 else if (XFIXNUM (val) < 0)
2944 mpz_add_ui (accum, accum, - XFIXNUM (val));
2780 else 2945 else
2781 overflow |= INT_SUBTRACT_WRAPV (accum, next, &accum); 2946 mpz_sub_ui (accum, accum, XFIXNUM (val));
2782 break; 2947 break;
2783 case Amult: 2948 case Amult:
2784 overflow |= INT_MULTIPLY_WRAPV (accum, next, &accum); 2949 if (BIGNUMP (val))
2950 mpz_mul (accum, accum, XBIGNUM (val)->value);
2951 else if (sizeof (EMACS_INT) > sizeof (long))
2952 {
2953 mpz_t tem;
2954 mpz_init (tem);
2955 mpz_set_intmax (tem, XFIXNUM (val));
2956 mpz_mul (accum, accum, tem);
2957 mpz_clear (tem);
2958 }
2959 else
2960 mpz_mul_si (accum, accum, XFIXNUM (val));
2785 break; 2961 break;
2786 case Adiv: 2962 case Adiv:
2787 if (! (argnum || nargs == 1)) 2963 if (! (argnum || nargs == 1))
2788 accum = next; 2964 {
2965 if (BIGNUMP (val))
2966 mpz_set (accum, XBIGNUM (val)->value);
2967 else
2968 mpz_set_intmax (accum, XFIXNUM (val));
2969 }
2789 else 2970 else
2790 { 2971 {
2791 if (next == 0) 2972 /* Note that a bignum can never be 0, so we don't need
2973 to check that case. */
2974 if (FIXNUMP (val) && XFIXNUM (val) == 0)
2792 xsignal0 (Qarith_error); 2975 xsignal0 (Qarith_error);
2793 if (INT_DIVIDE_OVERFLOW (accum, next)) 2976 if (BIGNUMP (val))
2794 overflow = true; 2977 mpz_tdiv_q (accum, accum, XBIGNUM (val)->value);
2978 else if (sizeof (EMACS_INT) > sizeof (long))
2979 {
2980 mpz_t tem;
2981 mpz_init (tem);
2982 mpz_set_intmax (tem, XFIXNUM (val));
2983 mpz_tdiv_q (accum, accum, tem);
2984 mpz_clear (tem);
2985 }
2795 else 2986 else
2796 accum /= next; 2987 {
2988 EMACS_INT value = XFIXNUM (val);
2989 bool negate = value < 0;
2990 if (negate)
2991 value = -value;
2992 mpz_tdiv_q_ui (accum, accum, value);
2993 if (negate)
2994 mpz_neg (accum, accum);
2995 }
2797 } 2996 }
2798 break; 2997 break;
2799 case Alogand: 2998 case Alogand:
2800 accum &= next; 2999 if (BIGNUMP (val))
3000 mpz_and (accum, accum, XBIGNUM (val)->value);
3001 else
3002 {
3003 mpz_t tem;
3004 mpz_init (tem);
3005 mpz_set_uintmax (tem, XUFIXNUM (val));
3006 mpz_and (accum, accum, tem);
3007 mpz_clear (tem);
3008 }
2801 break; 3009 break;
2802 case Alogior: 3010 case Alogior:
2803 accum |= next; 3011 if (BIGNUMP (val))
3012 mpz_ior (accum, accum, XBIGNUM (val)->value);
3013 else
3014 {
3015 mpz_t tem;
3016 mpz_init (tem);
3017 mpz_set_uintmax (tem, XUFIXNUM (val));
3018 mpz_ior (accum, accum, tem);
3019 mpz_clear (tem);
3020 }
2804 break; 3021 break;
2805 case Alogxor: 3022 case Alogxor:
2806 accum ^= next; 3023 if (BIGNUMP (val))
3024 mpz_xor (accum, accum, XBIGNUM (val)->value);
3025 else
3026 {
3027 mpz_t tem;
3028 mpz_init (tem);
3029 mpz_set_uintmax (tem, XUFIXNUM (val));
3030 mpz_xor (accum, accum, tem);
3031 mpz_clear (tem);
3032 }
2807 break; 3033 break;
2808 } 3034 }
2809 } 3035 }
2810 3036
2811 XSETINT (val, accum); 3037 return unbind_to (count, make_number (accum));
2812 return val;
2813} 3038}
2814 3039
2815static Lisp_Object 3040static Lisp_Object
@@ -2821,17 +3046,20 @@ float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code,
2821 3046
2822 for (; argnum < nargs; argnum++) 3047 for (; argnum < nargs; argnum++)
2823 { 3048 {
2824 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */ 3049 /* using args[argnum] as argument to CHECK_NUMBER_... */
2825 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 3050 val = args[argnum];
3051 CHECK_NUMBER_COERCE_MARKER (val);
2826 3052
2827 if (FLOATP (val)) 3053 if (FLOATP (val))
2828 { 3054 {
2829 next = XFLOAT_DATA (val); 3055 next = XFLOAT_DATA (val);
2830 } 3056 }
3057 else if (BIGNUMP (val))
3058 next = mpz_get_d (XBIGNUM (val)->value);
2831 else 3059 else
2832 { 3060 {
2833 args[argnum] = val; /* runs into a compiler bug. */ 3061 args[argnum] = val; /* runs into a compiler bug. */
2834 next = XINT (args[argnum]); 3062 next = XFIXNUM (args[argnum]);
2835 } 3063 }
2836 switch (code) 3064 switch (code)
2837 { 3065 {
@@ -2913,13 +3141,49 @@ Both must be integers or markers. */)
2913{ 3141{
2914 Lisp_Object val; 3142 Lisp_Object val;
2915 3143
2916 CHECK_NUMBER_COERCE_MARKER (x); 3144 CHECK_INTEGER_COERCE_MARKER (x);
2917 CHECK_NUMBER_COERCE_MARKER (y); 3145 CHECK_INTEGER_COERCE_MARKER (y);
2918 3146
2919 if (XINT (y) == 0) 3147 /* Note that a bignum can never be 0, so we don't need to check that
3148 case. */
3149 if (FIXNUMP (y) && XFIXNUM (y) == 0)
2920 xsignal0 (Qarith_error); 3150 xsignal0 (Qarith_error);
2921 3151
2922 XSETINT (val, XINT (x) % XINT (y)); 3152 if (FIXNUMP (x) && FIXNUMP (y))
3153 XSETINT (val, XFIXNUM (x) % XFIXNUM (y));
3154 else
3155 {
3156 mpz_t xm, ym, *xmp, *ymp;
3157 mpz_t result;
3158
3159 if (BIGNUMP (x))
3160 xmp = &XBIGNUM (x)->value;
3161 else
3162 {
3163 mpz_init (xm);
3164 mpz_set_intmax (xm, XFIXNUM (x));
3165 xmp = &xm;
3166 }
3167
3168 if (BIGNUMP (y))
3169 ymp = &XBIGNUM (y)->value;
3170 else
3171 {
3172 mpz_init (ym);
3173 mpz_set_intmax (ym, XFIXNUM (y));
3174 ymp = &ym;
3175 }
3176
3177 mpz_init (result);
3178 mpz_tdiv_r (result, *xmp, *ymp);
3179 val = make_number (result);
3180 mpz_clear (result);
3181
3182 if (xmp == &xm)
3183 mpz_clear (xm);
3184 if (ymp == &ym)
3185 mpz_clear (ym);
3186 }
2923 return val; 3187 return val;
2924} 3188}
2925 3189
@@ -2932,25 +3196,75 @@ Both X and Y must be numbers or markers. */)
2932 Lisp_Object val; 3196 Lisp_Object val;
2933 EMACS_INT i1, i2; 3197 EMACS_INT i1, i2;
2934 3198
2935 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (x); 3199 CHECK_NUMBER_COERCE_MARKER (x);
2936 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (y); 3200 CHECK_NUMBER_COERCE_MARKER (y);
3201
3202 /* Note that a bignum can never be 0, so we don't need to check that
3203 case. */
3204 if (FIXNUMP (y) && XFIXNUM (y) == 0)
3205 xsignal0 (Qarith_error);
2937 3206
2938 if (FLOATP (x) || FLOATP (y)) 3207 if (FLOATP (x) || FLOATP (y))
2939 return fmod_float (x, y); 3208 return fmod_float (x, y);
2940 3209
2941 i1 = XINT (x); 3210 if (FIXNUMP (x) && FIXNUMP (y))
2942 i2 = XINT (y); 3211 {
3212 i1 = XFIXNUM (x);
3213 i2 = XFIXNUM (y);
3214
3215 if (i2 == 0)
3216 xsignal0 (Qarith_error);
2943 3217
2944 if (i2 == 0) 3218 i1 %= i2;
2945 xsignal0 (Qarith_error);
2946 3219
2947 i1 %= i2; 3220 /* If the "remainder" comes out with the wrong sign, fix it. */
3221 if (i2 < 0 ? i1 > 0 : i1 < 0)
3222 i1 += i2;
2948 3223
2949 /* If the "remainder" comes out with the wrong sign, fix it. */ 3224 XSETINT (val, i1);
2950 if (i2 < 0 ? i1 > 0 : i1 < 0) 3225 }
2951 i1 += i2; 3226 else
3227 {
3228 mpz_t xm, ym, *xmp, *ymp;
3229 mpz_t result;
3230 int cmpr, cmpy;
3231
3232 if (BIGNUMP (x))
3233 xmp = &XBIGNUM (x)->value;
3234 else
3235 {
3236 mpz_init (xm);
3237 mpz_set_intmax (xm, XFIXNUM (x));
3238 xmp = &xm;
3239 }
3240
3241 if (BIGNUMP (y))
3242 ymp = &XBIGNUM (y)->value;
3243 else
3244 {
3245 mpz_init (ym);
3246 mpz_set_intmax (ym, XFIXNUM (y));
3247 ymp = &ym;
3248 }
3249
3250 mpz_init (result);
3251 mpz_mod (result, *xmp, *ymp);
3252
3253 /* Fix the sign if needed. */
3254 cmpr = mpz_sgn (result);
3255 cmpy = mpz_sgn (*ymp);
3256 if (cmpy < 0 ? cmpr > 0 : cmpr < 0)
3257 mpz_add (result, result, *ymp);
3258
3259 val = make_number (result);
3260 mpz_clear (result);
3261
3262 if (xmp == &xm)
3263 mpz_clear (xm);
3264 if (ymp == &ym)
3265 mpz_clear (ym);
3266 }
2952 3267
2953 XSETINT (val, i1);
2954 return val; 3268 return val;
2955} 3269}
2956 3270
@@ -2959,11 +3273,11 @@ minmax_driver (ptrdiff_t nargs, Lisp_Object *args,
2959 enum Arith_Comparison comparison) 3273 enum Arith_Comparison comparison)
2960{ 3274{
2961 Lisp_Object accum = args[0]; 3275 Lisp_Object accum = args[0];
2962 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (accum); 3276 CHECK_NUMBER_COERCE_MARKER (accum);
2963 for (ptrdiff_t argnum = 1; argnum < nargs; argnum++) 3277 for (ptrdiff_t argnum = 1; argnum < nargs; argnum++)
2964 { 3278 {
2965 Lisp_Object val = args[argnum]; 3279 Lisp_Object val = args[argnum];
2966 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 3280 CHECK_NUMBER_COERCE_MARKER (val);
2967 if (!NILP (arithcompare (val, accum, comparison))) 3281 if (!NILP (arithcompare (val, accum, comparison)))
2968 accum = val; 3282 accum = val;
2969 else if (FLOATP (val) && isnan (XFLOAT_DATA (val))) 3283 else if (FLOATP (val) && isnan (XFLOAT_DATA (val)))
@@ -3024,9 +3338,24 @@ of VALUE. If VALUE is negative, return the number of zero bits in the
3024representation. */) 3338representation. */)
3025 (Lisp_Object value) 3339 (Lisp_Object value)
3026{ 3340{
3027 CHECK_NUMBER (value); 3341 CHECK_INTEGER (value);
3028 EMACS_INT v = XINT (value) < 0 ? -1 - XINT (value) : XINT (value); 3342
3029 return make_number (EMACS_UINT_WIDTH <= UINT_WIDTH 3343 if (BIGNUMP (value))
3344 {
3345 if (mpz_sgn (XBIGNUM (value)->value) >= 0)
3346 return make_fixnum (mpz_popcount (XBIGNUM (value)->value));
3347 mpz_t tem;
3348 mpz_init (tem);
3349 mpz_neg (tem, XBIGNUM (value)->value);
3350 mpz_sub_ui (tem, tem, 1);
3351 Lisp_Object result = make_fixnum (mpz_popcount (tem));
3352 mpz_clear (tem);
3353 return result;
3354 }
3355
3356 eassume (FIXNUMP (value));
3357 EMACS_INT v = XFIXNUM (value) < 0 ? -1 - XFIXNUM (value) : XFIXNUM (value);
3358 return make_fixnum (EMACS_UINT_WIDTH <= UINT_WIDTH
3030 ? count_one_bits (v) 3359 ? count_one_bits (v)
3031 : EMACS_UINT_WIDTH <= ULONG_WIDTH 3360 : EMACS_UINT_WIDTH <= ULONG_WIDTH
3032 ? count_one_bits_l (v) 3361 ? count_one_bits_l (v)
@@ -3041,18 +3370,47 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
3041 3370
3042 Lisp_Object val; 3371 Lisp_Object val;
3043 3372
3044 CHECK_NUMBER (value); 3373 CHECK_INTEGER (value);
3045 CHECK_NUMBER (count); 3374 CHECK_FIXNUM (count);
3046 3375
3047 if (XINT (count) >= EMACS_INT_WIDTH) 3376 if (BIGNUMP (value))
3048 XSETINT (val, 0); 3377 {
3049 else if (XINT (count) > 0) 3378 mpz_t result;
3050 XSETINT (val, XUINT (value) << XINT (count)); 3379 mpz_init (result);
3051 else if (XINT (count) <= -EMACS_INT_WIDTH) 3380 if (XFIXNUM (count) >= 0)
3052 XSETINT (val, lsh ? 0 : XINT (value) < 0 ? -1 : 0); 3381 mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count));
3382 else if (lsh)
3383 mpz_tdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count));
3384 else
3385 mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count));
3386 val = make_number (result);
3387 mpz_clear (result);
3388 }
3053 else 3389 else
3054 XSETINT (val, (lsh ? XUINT (value) >> -XINT (count) 3390 {
3055 : XINT (value) >> -XINT (count))); 3391 /* Just do the work as bignums to make the code simpler. */
3392 mpz_t result;
3393 eassume (FIXNUMP (value));
3394 mpz_init (result);
3395
3396 mpz_set_intmax (result, XFIXNUM (value));
3397
3398 if (XFIXNUM (count) >= 0)
3399 mpz_mul_2exp (result, result, XFIXNUM (count));
3400 else if (lsh)
3401 {
3402 if (mpz_sgn (result) > 0)
3403 mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
3404 else
3405 mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
3406 }
3407 else /* ash */
3408 mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
3409
3410 val = make_number (result);
3411 mpz_clear (result);
3412 }
3413
3056 return val; 3414 return val;
3057} 3415}
3058 3416
@@ -3079,12 +3437,33 @@ DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
3079Markers are converted to integers. */) 3437Markers are converted to integers. */)
3080 (register Lisp_Object number) 3438 (register Lisp_Object number)
3081{ 3439{
3082 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number); 3440 CHECK_NUMBER_COERCE_MARKER (number);
3083 3441
3084 if (FLOATP (number)) 3442 if (FLOATP (number))
3085 return (make_float (1.0 + XFLOAT_DATA (number))); 3443 return (make_float (1.0 + XFLOAT_DATA (number)));
3086 3444
3087 XSETINT (number, XINT (number) + 1); 3445 if (BIGNUMP (number))
3446 {
3447 mpz_t num;
3448 mpz_init (num);
3449 mpz_add_ui (num, XBIGNUM (number)->value, 1);
3450 number = make_number (num);
3451 mpz_clear (num);
3452 }
3453 else
3454 {
3455 eassume (FIXNUMP (number));
3456 if (XFIXNUM (number) < MOST_POSITIVE_FIXNUM)
3457 XSETINT (number, XFIXNUM (number) + 1);
3458 else
3459 {
3460 mpz_t num;
3461 mpz_init (num);
3462 mpz_set_intmax (num, XFIXNUM (number) + 1);
3463 number = make_number (num);
3464 mpz_clear (num);
3465 }
3466 }
3088 return number; 3467 return number;
3089} 3468}
3090 3469
@@ -3093,12 +3472,33 @@ DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
3093Markers are converted to integers. */) 3472Markers are converted to integers. */)
3094 (register Lisp_Object number) 3473 (register Lisp_Object number)
3095{ 3474{
3096 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number); 3475 CHECK_NUMBER_COERCE_MARKER (number);
3097 3476
3098 if (FLOATP (number)) 3477 if (FLOATP (number))
3099 return (make_float (-1.0 + XFLOAT_DATA (number))); 3478 return (make_float (-1.0 + XFLOAT_DATA (number)));
3100 3479
3101 XSETINT (number, XINT (number) - 1); 3480 if (BIGNUMP (number))
3481 {
3482 mpz_t num;
3483 mpz_init (num);
3484 mpz_sub_ui (num, XBIGNUM (number)->value, 1);
3485 number = make_number (num);
3486 mpz_clear (num);
3487 }
3488 else
3489 {
3490 eassume (FIXNUMP (number));
3491 if (XFIXNUM (number) > MOST_NEGATIVE_FIXNUM)
3492 XSETINT (number, XFIXNUM (number) - 1);
3493 else
3494 {
3495 mpz_t num;
3496 mpz_init (num);
3497 mpz_set_intmax (num, XFIXNUM (number) - 1);
3498 number = make_number (num);
3499 mpz_clear (num);
3500 }
3501 }
3102 return number; 3502 return number;
3103} 3503}
3104 3504
@@ -3106,8 +3506,20 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
3106 doc: /* Return the bitwise complement of NUMBER. NUMBER must be an integer. */) 3506 doc: /* Return the bitwise complement of NUMBER. NUMBER must be an integer. */)
3107 (register Lisp_Object number) 3507 (register Lisp_Object number)
3108{ 3508{
3109 CHECK_NUMBER (number); 3509 CHECK_INTEGER (number);
3110 XSETINT (number, ~XINT (number)); 3510 if (BIGNUMP (number))
3511 {
3512 mpz_t value;
3513 mpz_init (value);
3514 mpz_com (value, XBIGNUM (number)->value);
3515 number = make_number (value);
3516 mpz_clear (value);
3517 }
3518 else
3519 {
3520 eassume (FIXNUMP (number));
3521 XSETINT (number, ~XFIXNUM (number));
3522 }
3111 return number; 3523 return number;
3112} 3524}
3113 3525
@@ -3121,7 +3533,7 @@ lowercase l) for small endian machines. */
3121 unsigned i = 0x04030201; 3533 unsigned i = 0x04030201;
3122 int order = *(char *)&i == 1 ? 108 : 66; 3534 int order = *(char *)&i == 1 ? 108 : 66;
3123 3535
3124 return make_number (order); 3536 return make_fixnum (order);
3125} 3537}
3126 3538
3127/* Because we round up the bool vector allocate size to word_size 3539/* Because we round up the bool vector allocate size to word_size
@@ -3474,7 +3886,7 @@ value from A's length. */)
3474 for (i = 0; i < nwords; i++) 3886 for (i = 0; i < nwords; i++)
3475 count += count_one_bits_word (adata[i]); 3887 count += count_one_bits_word (adata[i]);
3476 3888
3477 return make_number (count); 3889 return make_fixnum (count);
3478} 3890}
3479 3891
3480DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive, 3892DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive,
@@ -3493,16 +3905,16 @@ A is a bool vector, B is t or nil, and I is an index into A. */)
3493 ptrdiff_t nr_words; 3905 ptrdiff_t nr_words;
3494 3906
3495 CHECK_BOOL_VECTOR (a); 3907 CHECK_BOOL_VECTOR (a);
3496 CHECK_NATNUM (i); 3908 CHECK_FIXNAT (i);
3497 3909
3498 nr_bits = bool_vector_size (a); 3910 nr_bits = bool_vector_size (a);
3499 if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ 3911 if (XFIXNAT (i) > nr_bits) /* Allow one past the end for convenience */
3500 args_out_of_range (a, i); 3912 args_out_of_range (a, i);
3501 3913
3502 adata = bool_vector_data (a); 3914 adata = bool_vector_data (a);
3503 nr_words = bool_vector_words (nr_bits); 3915 nr_words = bool_vector_words (nr_bits);
3504 pos = XFASTINT (i) / BITS_PER_BITS_WORD; 3916 pos = XFIXNAT (i) / BITS_PER_BITS_WORD;
3505 offset = XFASTINT (i) % BITS_PER_BITS_WORD; 3917 offset = XFIXNAT (i) % BITS_PER_BITS_WORD;
3506 count = 0; 3918 count = 0;
3507 3919
3508 /* By XORing with twiddle, we transform the problem of "count 3920 /* By XORing with twiddle, we transform the problem of "count
@@ -3523,7 +3935,7 @@ A is a bool vector, B is t or nil, and I is an index into A. */)
3523 count = count_trailing_zero_bits (mword); 3935 count = count_trailing_zero_bits (mword);
3524 pos++; 3936 pos++;
3525 if (count + offset < BITS_PER_BITS_WORD) 3937 if (count + offset < BITS_PER_BITS_WORD)
3526 return make_number (count); 3938 return make_fixnum (count);
3527 } 3939 }
3528 3940
3529 /* Scan whole words until we either reach the end of the vector or 3941 /* Scan whole words until we either reach the end of the vector or
@@ -3550,7 +3962,7 @@ A is a bool vector, B is t or nil, and I is an index into A. */)
3550 count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD; 3962 count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD;
3551 } 3963 }
3552 3964
3553 return make_number (count); 3965 return make_fixnum (count);
3554} 3966}
3555 3967
3556 3968
@@ -3593,6 +4005,7 @@ syms_of_data (void)
3593 DEFSYM (Qlistp, "listp"); 4005 DEFSYM (Qlistp, "listp");
3594 DEFSYM (Qconsp, "consp"); 4006 DEFSYM (Qconsp, "consp");
3595 DEFSYM (Qsymbolp, "symbolp"); 4007 DEFSYM (Qsymbolp, "symbolp");
4008 DEFSYM (Qfixnump, "fixnump");
3596 DEFSYM (Qintegerp, "integerp"); 4009 DEFSYM (Qintegerp, "integerp");
3597 DEFSYM (Qnatnump, "natnump"); 4010 DEFSYM (Qnatnump, "natnump");
3598 DEFSYM (Qwholenump, "wholenump"); 4011 DEFSYM (Qwholenump, "wholenump");
@@ -3741,6 +4154,7 @@ syms_of_data (void)
3741 defsubr (&Sconsp); 4154 defsubr (&Sconsp);
3742 defsubr (&Satom); 4155 defsubr (&Satom);
3743 defsubr (&Sintegerp); 4156 defsubr (&Sintegerp);
4157 defsubr (&Sfixnump);
3744 defsubr (&Sinteger_or_marker_p); 4158 defsubr (&Sinteger_or_marker_p);
3745 defsubr (&Snumberp); 4159 defsubr (&Snumberp);
3746 defsubr (&Snumber_or_marker_p); 4160 defsubr (&Snumber_or_marker_p);
@@ -3766,6 +4180,7 @@ syms_of_data (void)
3766 defsubr (&Sthreadp); 4180 defsubr (&Sthreadp);
3767 defsubr (&Smutexp); 4181 defsubr (&Smutexp);
3768 defsubr (&Scondition_variable_p); 4182 defsubr (&Scondition_variable_p);
4183 defsubr (&Sbignump);
3769 defsubr (&Scar); 4184 defsubr (&Scar);
3770 defsubr (&Scdr); 4185 defsubr (&Scdr);
3771 defsubr (&Scar_safe); 4186 defsubr (&Scar_safe);
@@ -3843,13 +4258,13 @@ syms_of_data (void)
3843 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, 4258 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
3844 doc: /* The largest value that is representable in a Lisp integer. 4259 doc: /* The largest value that is representable in a Lisp integer.
3845This variable cannot be set; trying to do so will signal an error. */); 4260This variable cannot be set; trying to do so will signal an error. */);
3846 Vmost_positive_fixnum = make_number (MOST_POSITIVE_FIXNUM); 4261 Vmost_positive_fixnum = make_fixnum (MOST_POSITIVE_FIXNUM);
3847 make_symbol_constant (intern_c_string ("most-positive-fixnum")); 4262 make_symbol_constant (intern_c_string ("most-positive-fixnum"));
3848 4263
3849 DEFVAR_LISP ("most-negative-fixnum", Vmost_negative_fixnum, 4264 DEFVAR_LISP ("most-negative-fixnum", Vmost_negative_fixnum,
3850 doc: /* The smallest value that is representable in a Lisp integer. 4265 doc: /* The smallest value that is representable in a Lisp integer.
3851This variable cannot be set; trying to do so will signal an error. */); 4266This variable cannot be set; trying to do so will signal an error. */);
3852 Vmost_negative_fixnum = make_number (MOST_NEGATIVE_FIXNUM); 4267 Vmost_negative_fixnum = make_fixnum (MOST_NEGATIVE_FIXNUM);
3853 make_symbol_constant (intern_c_string ("most-negative-fixnum")); 4268 make_symbol_constant (intern_c_string ("most-negative-fixnum"));
3854 4269
3855 DEFSYM (Qwatchers, "watchers"); 4270 DEFSYM (Qwatchers, "watchers");