diff --git a/boot/pb/equates.h b/boot/pb/equates.h index e8047ba2a..016d37d95 100644 --- a/boot/pb/equates.h +++ b/boot/pb/equates.h @@ -1,4 +1,4 @@ -/* equates.h for Chez Scheme Version 10.3.0-pre-release.2 */ +/* equates.h for Chez Scheme Version 10.3.0-pre-release.3 */ /* Do not edit this file. It is automatically generated and */ /* specifically tailored to the version of Chez Scheme named */ @@ -1015,7 +1015,7 @@ typedef uint64_t U64; #define rtd_sealed 0x4 #define sbwp (ptr)0x4E #define scaled_shot_1_shot_flag -0x8 -#define scheme_version 0xA030002 +#define scheme_version 0xA030003 #define seginfo_generation_disp 0x1 #define seginfo_list_bits_disp 0x8 #define seginfo_space_disp 0x0 diff --git a/boot/pb/petite.boot b/boot/pb/petite.boot index c38bb5e26..358595994 100644 Binary files a/boot/pb/petite.boot and b/boot/pb/petite.boot differ diff --git a/boot/pb/scheme.boot b/boot/pb/scheme.boot index 8d8f356a8..62db5c591 100644 Binary files a/boot/pb/scheme.boot and b/boot/pb/scheme.boot differ diff --git a/boot/pb/scheme.h b/boot/pb/scheme.h index 79f39203e..bb5cc8dde 100644 --- a/boot/pb/scheme.h +++ b/boot/pb/scheme.h @@ -1,4 +1,4 @@ -/* scheme.h for Chez Scheme Version 10.3.0-pre-release.2 (pb) */ +/* scheme.h for Chez Scheme Version 10.3.0-pre-release.3 (pb) */ /* Do not edit this file. It is automatically generated and */ /* specifically tailored to the version of Chez Scheme named */ @@ -40,7 +40,7 @@ #endif /* Chez Scheme Version and machine type */ -#define VERSION "10.3.0-pre-release.2" +#define VERSION "10.3.0-pre-release.3" #define MACHINE_TYPE "pb" /* Integer typedefs */ diff --git a/mats/cptypes.ms b/mats/cptypes.ms index d9b1de2a7..780e7350d 100644 --- a/mats/cptypes.ms +++ b/mats/cptypes.ms @@ -59,6 +59,23 @@ #;[optimize-level (max (optimize-level) 2)]) (expand/optimize y)))])) +(define-syntax cptypes/first-equivalent-expansion? + ; When run-cp0 is call, use first #3%$cptypes and + ; then twice the cp0 function provided. + ; This checks that cptypes.ss doesn't mess up unusual combinations + ; that are reduced by cp0. + (syntax-rules () + [(_ x y) + (equivalent-expansion? + (parameterize ([run-cp0 (lambda (cp0 c) (cp0 (cp0 (#3%$cptypes c))))] + [#%$suppress-primitive-inlining #f] + #;[optimize-level (max (optimize-level) 2)]) + (expand/optimize x)) + (parameterize ([run-cp0 (lambda (cp0 c) (cp0 (cp0 (#3%$cptypes c))))] + [#%$suppress-primitive-inlining #f] + #;[optimize-level (max (optimize-level) 2)]) + (expand/optimize y)))])) + (mat cptypes-handcoded (cptypes-equivalent-expansion? '(vector? (vector)) ;actually reduced by folding, not cptypes @@ -664,6 +681,7 @@ (test-chain* '(fixnum? integer? real?)) (test-chain* '(fixnum? exact? number?)) ; exact? may raise an error (test-chain* '(bignum? exact? number?)) ; exact? may raise an error + (test-chain '(fixnum? (lambda (x) (and (integer? x) (exact? x))) (lambda (x) (and (number? x) (exact? x))) number?)) (test-chain '((lambda (x) (eqv? x (expt 256 100))) bignum? integer? real? number?)) (test-chain '((lambda (x) (eqv? 0.0 x)) flonum? real? number?)) (test-chain '((lambda (x) (eqv? 0.0 x)) flonum? cflonum? number?)) @@ -980,7 +998,7 @@ '(lambda (x) (when (fixnum? x) (sub1 x))) '(lambda (x) (when (fixnum? x) - (#3%$fxx+ x -1)))) + (#3%$fxx- x 1)))) (not (cptypes-equivalent-expansion? '(lambda (x) (when (fixnum? x) (fixnum? (sub1 x)))) @@ -1000,7 +1018,7 @@ '(lambda (x) (when (fixnum? x) (1- x))) '(lambda (x) (when (fixnum? x) - (#3%$fxx+ x -1)))) + (#3%$fxx- x 1)))) (cptypes-equivalent-expansion? '(lambda (x) (when (flonum? x) (1- x))) @@ -1010,7 +1028,7 @@ '(lambda (x) (when (fixnum? x) (-1+ x))) '(lambda (x) (when (fixnum? x) - (#3%$fxx+ x -1)))) + (#3%$fxx- x 1)))) (cptypes-equivalent-expansion? '(lambda (x) (when (flonum? x) (-1+ x))) @@ -1026,9 +1044,9 @@ (abs x))) '(lambda (x) (when (fixnum? x) (let ([t x]) - (if (#3%fx= t (most-negative-fixnum)) - (pariah (- (most-negative-fixnum))) - (#3%fxabs t)))))) + (if (#3%fx>= t 0) + t + (#3%$fxx- t)))))) (cptypes-equivalent-expansion? ; unexpected, but correct '(lambda (x) (when (bignum? x) (bignum? (abs x)))) @@ -1043,6 +1061,279 @@ '(flonum? real? (lambda (x) (and (integer? x) (exact? x))))) ) +(mat cptypes-plus + (test-closed1 '(+ (lambda (x) (+ x 1)) (lambda (x) (+ x x))) + '(flonum? real? (lambda (x) (and (integer? x) (exact? x))) (lambda (x) (and (number? x) (exact? x))))) + (not (cptypes-equivalent-expansion? ; integer? is not closed + '(lambda (x) (when (integer? x) (integer? (+ x x)))) + '(lambda (x) (when (integer? x) (+ x x) #t)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (fixnum? x) (fixnum? y)) + (+ x y))) + '(lambda (x y) (when (and (fixnum? x) (fixnum? y)) + (#3%$fxx+ x y)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (flonum? x) (flonum? y)) + (+ x y))) + '(lambda (x y) (when (and (flonum? x) (flonum? y)) + (#3%fl+ x y)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (number? x) (number? y)) + (+ x y))) + '(lambda (x y) (when (and (number? x) (number? y)) + (#3%+ x y)))) + ; in cp0, partial-folder reverses (+ x 1) to (+ 1 x) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (+ 1 x))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx+ 1 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (+ 1 x))) + '(lambda (x) (when (flonum? x) + (#3%fl+ 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (+ 1 x))) + '(lambda (x) (when (number? x) + (#3%+ 1 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (+ 1.0 x))) + '(lambda (x) (when (fixnum? x) + (#3%fl+ 1.0 (fixnum->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (+ -0.0 x))) + '(lambda (x) (when (fixnum? x) + (#3%fl+ -0.0 (if (#3%eqv? x 0) -0.0 (fixnum->flonum x)))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (bignum? x) + (+ -0.0 x))) + '(lambda (x) (when (bignum? x) + (#3%fl+ -0.0 (real->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (+ 1.0 x))) + '(lambda (x) (when (flonum? x) + (#3%fl+ 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (+ 1.0 x))) + '(lambda (x) (when (number? x) + (#3%+ 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (+ 1 x x))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx+ 1 x x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (+ 1 x x))) + '(lambda (x) (when (flonum? x) + (#3%fl+ 1.0 x x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (+ 1 x x))) + '(lambda (x) (when (number? x) + (#3%+ 1 x x)))) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+)) + '(lambda (x) 0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+ 0)) + '(lambda (x) 0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+ 0 0)) + '(lambda (x) 0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+ 0 0.0)) + '(lambda (x) 0.0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+ 0 -0.0)) + '(lambda (x) -0.0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (+ 0.0 -0.0)) + '(lambda (x) 0.0)) +) + +(mat cptypes-minus + (test-closed1 '(- (lambda (x) (- x 1)) (lambda (x) (- 1 x)) (lambda (x) (- x x))) + '(flonum? real? (lambda (x) (and (integer? x) (exact? x))) (lambda (x) (and (number? x) (exact? x))))) + (not (cptypes-equivalent-expansion? ; integer? is not closed + '(lambda (x y) (when (and (integer? x) (integer? y)) (integer? (- x y)))) + '(lambda (x y) (when (and (integer? x) (integer? y)) (- x y) #t)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (fixnum? x) (fixnum? y)) + (- x y))) + '(lambda (x y) (when (and (fixnum? x) (fixnum? y)) + (#3%$fxx- x y)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (flonum? x) (flonum? y)) + (- x y))) + '(lambda (x y) (when (and (flonum? x) (flonum? y)) + (#3%fl- x y)))) + (cptypes-equivalent-expansion? + '(lambda (x y) (when (and (number? x) (number? y)) + (- x y))) + '(lambda (x y) (when (and (number? x) (number? y)) + (#3%- x y)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- 1 x))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx- 1 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- 1 x))) + '(lambda (x) (when (flonum? x) + (#3%fl- 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- 1 x))) + '(lambda (x) (when (number? x) + (#3%- 1 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- x 1))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx- x 1)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- x 1))) + '(lambda (x) (when (flonum? x) + (#3%fl- x 1.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- x 1))) + '(lambda (x) (when (number? x) + (#3%- x 1)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- 1.0 x))) + '(lambda (x) (when (fixnum? x) + (#3%fl- 1.0 (fixnum->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- x 1.0))) + '(lambda (x) (when (fixnum? x) + (#3%fl- (fixnum->flonum x) 1.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- -0.0 x))) + '(lambda (x) (when (fixnum? x) + (#3%fl- -0.0 (fixnum->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (bignum? x) + (- -0.0 x))) + '(lambda (x) (when (bignum? x) + (#3%fl- -0.0 (real->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- x -0.0))) + '(lambda (x) (when (fixnum? x) + (#3%fl- (fixnum->flonum x) -0.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (bignum? x) + (- x -0.0))) + '(lambda (x) (when (bignum? x) + (#3%fl- (real->flonum x) -0.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- 0.0 x))) + '(lambda (x) (when (fixnum? x) + (#3%fl- 0.0 (fixnum->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (bignum? x) + (- 0.0 x))) + '(lambda (x) (when (bignum? x) + (#3%fl- 0.0 (real->flonum x))))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- x 0.0))) + '(lambda (x) (when (fixnum? x) + (#3%fl- (if (#3%eqv? x 0) -0.0 (fixnum->flonum x)) 0.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (bignum? x) + (- x 0.0))) + '(lambda (x) (when (bignum? x) + (#3%fl- (real->flonum x) 0.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- 1.0 x))) + '(lambda (x) (when (flonum? x) + (#3%fl- 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- 1.0 x))) + '(lambda (x) (when (number? x) + (#3%- 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- x 1.0))) + '(lambda (x) (when (flonum? x) + (#3%fl- x 1.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- x 1.0))) + '(lambda (x) (when (number? x) + (#3%- x 1.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- x 1.0))) + '(lambda (x) (when (number? x) + (#3%- x 1.0)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- 1 x x))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx- 1 x x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- 1 x x))) + '(lambda (x) (when (flonum? x) + (#3%fl- 1.0 x x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- 1 x x))) + '(lambda (x) (when (number? x) + (#3%- 1 x x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (fixnum? x) + (- x 1 x))) + '(lambda (x) (when (fixnum? x) + (#3%$fxx- x 1 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (flonum? x) + (- x 1 x))) + '(lambda (x) (when (flonum? x) + (#3%fl- x 1.0 x)))) + (cptypes-equivalent-expansion? + '(lambda (x) (when (number? x) + (- x 1 x))) + '(lambda (x) (when (number? x) + (#3%- x 1 x)))) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- 0)) + '(lambda (x) 0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- 0 0)) + '(lambda (x) 0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- 0 0.0)) + '(lambda (x) -0.0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- 0 -0.0)) + '(lambda (x) 0.0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- 0.0 -0.0)) + '(lambda (x) 0.0)) + (cptypes/first-equivalent-expansion? + '(lambda (x) (- -0.0 0.0)) + '(lambda (x) -0.0)) +) + (mat cptypes-rest-argument (cptypes/nocp0-equivalent-expansion? '((lambda (x . r) (pair? r)) 1) diff --git a/release_notes/release_notes.stex b/release_notes/release_notes.stex index b4c45bea8..208007602 100644 --- a/release_notes/release_notes.stex +++ b/release_notes/release_notes.stex @@ -139,6 +139,7 @@ and \scheme{inexact?}, . The type recovery pass has improved support for \scheme{cfl+} and similar functions. Also improve the support of predicates, in particular integer?, zero? and similar predicates. +Also, add suport for \scheme{+} abd \scheme{-}. \subsection{Unicode 16.0.0 support (10.3.0)} diff --git a/s/cmacros.ss b/s/cmacros.ss index afdd83a69..37a576994 100644 --- a/s/cmacros.ss +++ b/s/cmacros.ss @@ -357,7 +357,7 @@ ;; --------------------------------------------------------------------- ;; Version and machine types: -(define-constant scheme-version #x0a030002) +(define-constant scheme-version #x0a030003) (define-syntax define-machine-types (lambda (x) diff --git a/s/cp0.ss b/s/cp0.ss index 348a190d2..2e9da878e 100644 --- a/s/cp0.ss +++ b/s/cp0.ss @@ -3077,6 +3077,7 @@ ; the multiply case. maybe shouldn't bother with nans anyway. (partial-folder plus + + 0 generic-nan?) (partial-folder plus fx+ + 0 (lambda (x) #f) 3) + (partial-folder plus $fxx+ + 0 (lambda (x) #f)) (r6rs-fixnum-partial-folder plus r6rs:fx+ fx+ + 0 (lambda (x) #f) 3) (r6rs-fixnum-partial-folder plus fx+/wraparound fx+/wraparound + 0 (lambda (x) #f) 3) (partial-folder plus fl+ fl+ -0.0 fl-nan? #f obviously-fl?) @@ -3094,6 +3095,7 @@ ; to 0, but (/ 0 n) is only 0 if divisor turns out not to be 0. (partial-folder minus - - 0) (partial-folder minus fx- - 0) + (partial-folder minus $fxx- - 0) (r6rs-fixnum-partial-folder minus r6rs:fx- fx- - 0) (r6rs-fixnum-partial-folder minus fx-/wraparound fx-/wraparound - 0) (partial-folder minus fl- fl- -0.0) diff --git a/s/cpprim.ss b/s/cpprim.ss index 5794b33e7..320dd75b8 100644 --- a/s/cpprim.ss +++ b/s/cpprim.ss @@ -1750,12 +1750,30 @@ ,t)) (goto ,Lfalse))))]) (define-inline 3 $fxx+ + [() `(immediate ,(fix 0))] + [(e) (ensure-single-valued e)] [(e1 e2) (bind #t (e1 e2) (bind #f ([t (%inline +/ovfl ,e1 ,e2)]) `(if (inline ,(make-info-condition-code 'overflow #f #t) ,%condition-code) ,(build-libcall #t src sexpr + e1 e2) - ,t)))]) + ,t)))] + [e* #f]) + (define-inline 3 $fxx- + [(e) + (bind #t (e) + (bind #f ([t (%inline -/ovfl (immediate ,(fix 0)) ,e)]) + `(if (inline ,(make-info-condition-code 'overflow #f #t) ,%condition-code) + ,(build-libcall #t src sexpr - `(immediate ,(fix 0)) e) + ,t)))] + [(e1 e2) + (bind #t (e1 e2) + (bind #f ([t (%inline -/ovfl ,e1 ,e2)]) + `(if (inline ,(make-info-condition-code 'overflow #f #t) ,%condition-code) + ,(build-libcall #t src sexpr - e1 e2) + ,t)))] + [(e1 . e*) #f]) + (let () (define (go src sexpr e1 e2) (let ([Llib (make-local-label 'Llib)]) diff --git a/s/cptypes-lattice.ss b/s/cptypes-lattice.ss index 04e776a87..2d58c6131 100644 --- a/s/cptypes-lattice.ss +++ b/s/cptypes-lattice.ss @@ -69,6 +69,11 @@ real-pred number-pred flzero-pred + flinteger-pred + exact-real-pred + exact-pred + inexact-pred + integer-pred $fixmediate-pred $list-pred ; immutable lists list-pair-pred diff --git a/s/cptypes.ss b/s/cptypes.ss index 83204b64f..8f3742145 100644 --- a/s/cptypes.ss +++ b/s/cptypes.ss @@ -355,6 +355,49 @@ Notes: [(ref ,maybe-src ,x) (and (not (prelex-assigned x)) x)] [else #f]))) + (define (real-expr->flonum-expr x r) + ; Transform 0 into 0.0 as usual + ; Assume (predicate-implies r real-pred) + (cond + [(and (Lsrc? r) + (nanopass-case (Lsrc Expr) r + [(quote ,d) d] + [else #f])) => + (lambda (d) (make-1seq 'value x `(quote ,(real->flonum d))))] + [(predicate-implies? r flonum-pred) + x] + [else + (let ([->flonum-name (if (predicate-implies? r fixnum-pred) + 'fixnum->flonum + 'real->flonum)]) + `(call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x))])) + + (define (real-expr->flonum-expr/- x r) + ; Transform 0 into -0.0 instead of 0.0 + ; Assume (predicate-implies r real-pred) + (cond + [(and (Lsrc? r) + (nanopass-case (Lsrc Expr) r + [(quote ,d) d] + [else #f])) => + (lambda (d) (make-1seq 'value x `(quote ,(if (eqv? d 0) -0.0 (real->flonum d)))))] + [(predicate-implies? r flonum-pred) + x] + [else + (let ([->flonum-name (if (predicate-implies? r fixnum-pred) + 'fixnum->flonum + 'real->flonum)]) + (cond + [(predicate-disjoint? r `(quote 0)) + `(call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x)] + [else + (build-let 'value (list x) (list r) + (lambda (x*) + (let ([x (car x*)]) + `(if (call ,(make-preinfo-call) ,(lookup-primref 3 'eqv?) ,x (quote 0)) + (quote -0.0) + (call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x)))))]))])) + (define (filter/head+rest pred? l) ; (filter/head+rest odd? '(1 3 2 5 4 6)) ; ==> (values '(1 3) '(2 5 4 6)) @@ -1135,13 +1178,123 @@ Notes: (and (eq? ctxt 'test) (pred-env-add/ref ntypes val (rtd->record-predicate rtd #t) plxc)) #f)]))]) + + (let () + (define (predicate-implies-real? r) (predicate-implies? r real-pred)) + (define (predicate-implies-fixnum? r) (predicate-implies? r fixnum-pred)) + (define (predicate-implies-integer? r) (predicate-implies? r integer-pred)) + (define (predicate-implies-flonum? r) (predicate-implies? r flonum-pred)) + (define (predicate-implies-exact? r) (predicate-implies? r exact-pred)) + (define (predicate-implies-inexact? r) (predicate-implies? r inexact-pred)) + + (define (predicate-close/plus r* prim) + (cond + [(andmap predicate-implies-exact? r*) + (if (andmap predicate-implies-real? r*) + (if (andmap predicate-implies-integer? r*) + exact-integer-pred + exact-real-pred) + exact-pred)] + [(ormap predicate-implies-inexact? r*) + (if (andmap predicate-implies-real? r*) + flonum-pred + inexact-pred)] + [else + (if (andmap predicate-implies-real? r*) + real-pred + number-pred)])) + + (define-specialize 2 + + [() (values `(quote 0) `(quote 0) ntypes #f #f)] + [(x) (values `(call ,preinfo ,pr ,x) + (predicate-intersect (get-type x) number-pred) ntypes #f #f)] + [x* ; x* has at least 2 arguments + (let* ([r* (get-type x*)] + [ret (predicate-close/plus + (map (lambda (r) (predicate-intersect r number-pred)) r*) + pr)] + [ir (and (andmap predicate-implies-real? r*) + (cond + [(andmap predicate-implies-fixnum? r*) + `(call ,preinfo ,(lookup-primref 3 '$fxx+) ,x* ...)] + [(cond + [(enable-arithmetic-left-associative) + ; if they can't be reordered, check that at least + ; one of the first two is a flonum + (or (predicate-implies-flonum? (car r*)) + (predicate-implies-flonum? (cadr r*)))] + [else + ; otherwise, checkt that all or all but one are flonums, + ; in case they are reordered + (let-values ([(head* rest*) + (filter/head+rest predicate-implies-flonum? r*)]) + (or (null? rest*) + (andmap predicate-implies-flonum? (cdr rest*))))]) + (cond + [(ormap (lambda (r) (and (predicate-disjoint? r `(quote -0.0)) + (predicate-disjoint? r `(quote 0)))) + r*) + ; If one argument is neither 0 or -0.0 it's possible + ; to replace 0 with 0.0 instead of -0.0 + ; because the rounding mode is never FE_DOWNWARD + `(call ,preinfo ,(lookup-primref 3 'fl+) + ,(map real-expr->flonum-expr x* r*) ...)] + [else + `(call ,preinfo ,(lookup-primref 3 'fl+) + ,(map real-expr->flonum-expr/- x* r*) ...)])] + [else + #f]))]) + (values (or ir `(call ,preinfo ,pr ,x* ...)) ret ntypes #f #f))]) + + (define-specialize 2 - + [(x) (values `(call ,preinfo ,pr ,x) + (predicate-intersect (get-type x) number-pred) ntypes #f #f)] + [x* ; x* has at least 2 arguments + (let* ([r* (get-type x*)] + [ret (predicate-close/plus + (map (lambda (r) (predicate-intersect r number-pred)) r*) + pr)] + [ir (and (andmap predicate-implies-real? r*) + (cond + [(andmap predicate-implies-fixnum? r*) + `(call ,preinfo ,(lookup-primref 3 '$fxx-) ,x* ...)] + [(or ; check if the first argument is a flonum + (predicate-implies-flonum? (car r*)) + (cond + [(enable-arithmetic-left-associative) + ; if they can't be reordered, check that the second + ; is a flonum + (predicate-implies-flonum? (cadr r*))] + [else + ; otherwise, checkt that all are flonums, + ; in case they are reordered + (andmap predicate-implies-flonum? (cdr r*))])) + (cond + [(or (and (predicate-disjoint? (car r*) `(quote -0.0)) + (predicate-disjoint? (car r*) `(quote 0))) + (ormap (lambda (r) (and (predicate-disjoint? r `(quote 0.0)) + (predicate-disjoint? r `(quote 0)))) + (cdr r*))) + ; The only way to get a result -0.0 is when the first + ; argument is -0.0 and the rest are 0.0, or any of them is 0 + ; because the rounding mode is never FE_DOWNWARD + `(call ,preinfo ,(lookup-primref 3 'fl-) + ,(map real-expr->flonum-expr x* r*) ...)] + [else + `(call ,preinfo ,(lookup-primref 3 'fl-) + ,(real-expr->flonum-expr/- (car x*) (car r*)) + ,(map real-expr->flonum-expr (cdr x*) (cdr r*)) ...)])] + [else + #f]))]) + (values (or ir `(call ,preinfo ,pr ,x* ...)) ret ntypes #f #f))]) + ) (define-specialize 2 (add1 sub1 1+ 1- -1+) [(n) (let ([r (get-type n)]) (cond [(predicate-implies? r fixnum-pred) - (let ([delta (if (memq prim-name '(add1 1+)) 1 -1)]) - (values `(call ,preinfo ,(lookup-primref 3 '$fxx+) ,n (quote ,delta)) + (let ([fxprim-name (if (memq prim-name '(add1 1+)) '$fxx+ '$fxx-)]) + (values `(call ,preinfo ,(lookup-primref 3 fxprim-name) ,n (quote 1)) exact-integer-pred ntypes #f #f))] [(predicate-implies? r exact-integer-pred) (values `(call ,preinfo ,pr ,n) @@ -1161,9 +1314,9 @@ Notes: (values (build-let ctxt (list n) (list r) (lambda (n*) (let ([n (car n*)]) - `(if (call ,(make-preinfo-call) ,(lookup-primref 3 'fx=) ,n (quote ,(constant most-negative-fixnum))) - ,(make-seq ctxt `(pariah) `(quote ,(- (constant most-negative-fixnum)))) - (call ,preinfo ,(lookup-primref 3 'fxabs) ,n))))) + `(if (call ,(make-preinfo-call) ,(lookup-primref 3 'fx>=) ,n (quote 0)) + ,n + (call ,preinfo ,(lookup-primref 3 '$fxx-) ,n))))) exact-integer-pred ntypes #f #f)] [(predicate-implies? r bignum-pred) (values `(call ,preinfo ,pr ,n) diff --git a/s/mathprims.ss b/s/mathprims.ss index 2f86f2a8a..bb0888430 100644 --- a/s/mathprims.ss +++ b/s/mathprims.ss @@ -524,10 +524,49 @@ (#3%$fxu< x y))) (set! $fxx+ - (lambda (x y) - (unless (fixnum? x) (fxargerr '$fxx+ x)) - (unless (fixnum? y) (fxargerr '$fxx+ y)) - (#3%$fxx+ x y))) + (case-lambda + [(x1 x2) + (unless (fixnum? x1) (fxargerr '$fxx+ x1)) + (unless (fixnum? x2) (fxargerr '$fxx+ x2)) + (#3%$fxx+ x1 x2)] + [(x1 x2 x3) + (unless (fixnum? x1) (fxargerr '$fxx+ x1)) + (unless (fixnum? x2) (fxargerr '$fxx+ x2)) + (unless (fixnum? x3) (fxargerr '$fxx+ x3)) + (#3%+ (#3%$fxx+ x1 x2) x3)] + [(x1 x2 x3 . rest) + (unless (fixnum? x1) (fxargerr '$fxx+ x1)) + (unless (fixnum? x2) (fxargerr '$fxx+ x2)) + (let loop ([x1 (#3%$fxx+ x1 x2)] [x3 x3] [rest rest]) + (unless (fixnum? x3) (fxargerr '$fxx+ x3)) + (let ([x (#3%+ x1 x3)]) + (if (null? rest) x (loop x (car rest) (cdr rest)))))] + [(x1) + (unless (fixnum? x1) (fxargerr '$fxx+ x1)) + x1] + [() 0])) + + (set! $fxx- + (case-lambda + [(x1 x2) + (unless (fixnum? x1) (fxargerr '$fxx- x1)) + (unless (fixnum? x2) (fxargerr '$fxx- x2)) + (#3%$fxx- x1 x2)] + [(x1 x2 x3) + (unless (fixnum? x1) (fxargerr '$fxx- x1)) + (unless (fixnum? x2) (fxargerr '$fxx- x2)) + (unless (fixnum? x3) (fxargerr '$fxx- x3)) + (#3%- (#3%$fxx- x1 x2) x3)] + [(x1 x2 x3 . rest) + (unless (fixnum? x1) (fxargerr '$fxx- x1)) + (unless (fixnum? x2) (fxargerr '$fxx- x2)) + (let loop ([x1 (#3%$fxx- x1 x2)] [x3 x3] [rest rest]) + (unless (fixnum? x3) (fxargerr '$fxx- x3)) + (let ([x (#3%- x1 x3)]) + (if (null? rest) x (loop x (car rest) (cdr rest)))))] + [(x1) + (unless (fixnum? x1) (fxargerr '$fxx- x1)) + (#3%$fxx- x1)])) (define-addop fxlogand) (define-addop fxlogior) diff --git a/s/primdata.ss b/s/primdata.ss index 4aef41181..7d8c61f25 100644 --- a/s/primdata.ss +++ b/s/primdata.ss @@ -211,9 +211,9 @@ (nan? [sig [(real) -> (boolean)]] [pred nan] [flags pure mifoldable discard safeongoodargs cptypes2]) (max [sig [(real real ...) -> (real)]] [flags arith-op mifoldable discard safeongoodargs ieee r5rs cptypes2]) (min [sig [(real real ...) -> (real)]] [flags arith-op mifoldable discard safeongoodargs ieee r5rs cptypes2]) - (+ [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs]) + (+ [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs cptypes2]) (* [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs]) - (- [sig [(number number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs]) + (- [sig [(number number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs cptypes2]) (/ [sig [(number number ...) -> (number)]] [flags arith-op partial-folder ieee r5rs]) (abs [sig [(real) -> (real)]] [flags arith-op mifoldable discard safeongoodargs ieee r5rs cptypes2]) (div-and-mod [sig [(real real) -> (real real)]] [flags mifoldable+ discard]) @@ -2215,7 +2215,8 @@ ($fxu< [flags single-valued pure cp02]) ($fxvector-ref-check? [sig [(ptr ptr) -> (boolean)]] [flags unrestricted pure]) ($fxvector-set!-check? [sig [(ptr ptr) -> (boolean)]] [flags unrestricted discard]) - ($fxx+ [sig [(fixnum fixnum) -> (sint)]] [flags arith-op safeongoodargs]) + ($fxx- [sig [(fixnum fixnum ...) -> (sint)]] [flags arith-op partial-folder safeongoodargs]) + ($fxx+ [sig [(fixnum ...) -> (sint)]] [flags arith-op partial-folder safeongoodargs]) ($gc-cpu-time [flags true]) ($gc-real-time [flags true]) ($generation [flags single-valued]) diff --git a/s/prims.ss b/s/prims.ss index effbd8c5b..89648023e 100644 --- a/s/prims.ss +++ b/s/prims.ss @@ -832,10 +832,6 @@ (lambda (x y) ($fx+? x y))) -(define $fxx+ - (lambda (x y) - ($fxx+ x y))) - (define $fx-? (lambda (x y) ($fx-? x y))) diff --git a/s/reboot.ss b/s/reboot.ss index b37419641..05fe9e6f9 100644 --- a/s/reboot.ss +++ b/s/reboot.ss @@ -310,6 +310,12 @@ (define-primitive $integer-32? #%$integer-32?) (define-primitive $integer-64? #%$integer-64?) (define-primitive $fxu< #%$fxu<) +(define-primitive $fxx+ (lambda args (if (andmap fixnum? args) + (apply + args) + (error '$fxx+ "not a fixnum in ~s" args)))) +(define-primitive $fxx- (lambda args (if (andmap fixnum? args) + (apply - args) + (error '$fxx- "not a fixnum in ~s" args)))) (define-primitive $stencil-vector? (lambda (v) #f)) (define-primitive $system-stencil-vector? (lambda (v) #f)) (define-primitive $symbol-name #%$symbol-name)