fixed a bug in quotient and div when given (least-fixnum) and -1.

This commit is contained in:
Abdulaziz Ghuloum 2008-07-26 12:28:51 -07:00
parent 4909a9ef08
commit 3b80d4f321
9 changed files with 53 additions and 21 deletions

View File

@ -534,7 +534,7 @@
(S (cadr rands) (S (cadr rands)
(lambda (s) (lambda (s)
(make-asm-instr op d s))))] (make-asm-instr op d s))))]
[(remainder) [(int-quotient)
(S* rands (S* rands
(lambda (rands) (lambda (rands)
(seq* (seq*
@ -542,7 +542,7 @@
(make-asm-instr 'cltd edx eax) (make-asm-instr 'cltd edx eax)
(make-asm-instr 'idiv eax (cadr rands)) (make-asm-instr 'idiv eax (cadr rands))
(make-set d eax))))] (make-set d eax))))]
[(quotient) [(int-remainder)
(S* rands (S* rands
(lambda (rands) (lambda (rands)
(seq* (seq*
@ -2308,9 +2308,12 @@
(unless (symbol? a) (unless (symbol? a)
(error who "invalid arg to idiv")) (error who "invalid arg to idiv"))
(cond (cond
[(disp? b) [(or (var? b) (symbol? b)) x]
(error who "invalid arg to idiv" b)] [else
[else x])] (let ([u (mku)])
(make-seq
(E (make-asm-instr 'move u b))
(E (make-asm-instr 'idiv a u))))])]
[(sll sra srl sll/overflow) [(sll sra srl sll/overflow)
(unless (or (constant? b) (unless (or (constant? b)
(eq? b ecx)) (eq? b ecx))

View File

@ -171,7 +171,11 @@
(die 'fxquotient "not a fixnum" y)) (die 'fxquotient "not a fixnum" y))
(when ($fxzero? y) (when ($fxzero? y)
(die 'fxquotient "zero dividend" y)) (die 'fxquotient "zero dividend" y))
($fxquotient x y))) (if (eq? y -1)
(if (eq? x (least-fixnum))
(die 'fxquotient "overflow" x y)
($fx- 0 x))
($fxquotient x y))))
(define fxremainder (define fxremainder
(lambda (x y) (lambda (x y)

View File

@ -682,7 +682,7 @@
[(idivl dst) [(idivl dst)
(cond (cond
[(reg? dst) (CR* #xF7 '/7 dst ac)] [(reg? dst) (CR* #xF7 '/7 dst ac)]
[(mem? dst) (CR* #xF7 '/7 dst ac)] [(mem? dst) (CR* #xF7 '/7 dst ac)]
[else (die who "invalid" instr)])] [else (die who "invalid" instr)])]
[(pushl dst) [(pushl dst)
(cond (cond

View File

@ -1632,6 +1632,15 @@
(string-append (string-append
($number->string xr r) (imag xi r) "i")]))] ($number->string xr r) (imag xi r) "i")]))]
[else (die 'number->string "not a number" x)]))) [else (die 'number->string "not a number" x)])))
(define do-warn
(lambda ()
(set! do-warn values)
(raise-continuable
(condition
(make-warning)
(make-who-condition 'number->string)
(make-message-condition
"precision argument is not supported")))))
(define number->string (define number->string
(case-lambda (case-lambda
[(x) ($number->string x 10)] [(x) ($number->string x 10)]
@ -1640,8 +1649,8 @@
(die 'number->string "invalid radix" r)) (die 'number->string "invalid radix" r))
($number->string x r)] ($number->string x r)]
[(x r precision) [(x r precision)
(die 'number->string ;(do-warn)
"BUG: precision is not supported yet")]))) (number->string x r)])))
(define modulo (define modulo
(lambda (n m) (lambda (n m)
@ -2412,8 +2421,9 @@
[(fixnum? x) [(fixnum? x)
(cond (cond
[(fixnum? y) [(fixnum? y)
(values (fxquotient x y) (if (eq? y -1)
(fxremainder x y))] (values (- x) 0)
(values (fxquotient x y) (fxremainder x y)))]
[(bignum? y) (values 0 x)] [(bignum? y) (values 0 x)]
[(flonum? y) [(flonum? y)
(let ([v ($flonum->exact y)]) (let ([v ($flonum->exact y)])
@ -3235,6 +3245,7 @@
[(and (fixnum? n) (fixnum? m)) [(and (fixnum? n) (fixnum? m))
(cond (cond
[(eq? m 0) (error 'div "division by 0")] [(eq? m 0) (error 'div "division by 0")]
[(eq? m -1) (- n)]
[else [else
(let ([d0 ($fxquotient n m)]) (let ([d0 ($fxquotient n m)])
(if ($fx>= n ($fx* d0 m)) (if ($fx>= n ($fx* d0 m))

View File

@ -1 +1 @@
1553 1554

View File

@ -495,6 +495,8 @@
[$fxsra $fx] [$fxsra $fx]
[$fxquotient $fx] [$fxquotient $fx]
[$fxmodulo $fx] [$fxmodulo $fx]
[$int-quotient $fx]
[$int-remainder $fx]
[$fxlogxor $fx] [$fxlogxor $fx]
[$fxlogor $fx] [$fxlogor $fx]
[$fxlognot $fx] [$fxlognot $fx]

View File

@ -896,18 +896,24 @@
(define-primop $fxquotient unsafe (define-primop $fxquotient unsafe
[(V a b) [(V a b)
(with-tmp ([b (T b)]) ;;; FIXME: why is quotient called remainder? (with-tmp ([b (T b)]) ;;; FIXME: why is quotient called remainder?
(prm 'sll (prm 'remainder (T a) b) (K fx-shift)))] (prm 'sll (prm 'int-quotient (T a) b) (K fx-shift)))]
[(P a b) (K #t)] [(P a b) (K #t)]
[(E a b) (nop)]) [(E a b) (nop)])
(define-primop $int-quotient unsafe
[(V a b)
(prm 'sll (prm 'int-quotient (T a) (T b)) (K fx-shift))])
(define-primop $int-remainder unsafe
[(V a b) (prm 'int-remainder (T a))])
(define-primop $fxmodulo unsafe (define-primop $fxmodulo unsafe
[(V a b) [(V a b)
(with-tmp ([b (T b)]) ;;; FIXME: why is modulo called quotient? (with-tmp ([b (T b)])
(with-tmp ([c (prm 'logand b (with-tmp ([c (prm 'logand b
(prm 'sra (prm 'logxor b (T a)) (prm 'sra (prm 'logxor b (T a))
(K (sub1 (* 8 wordsize)))))]) (K (sub1 (* 8 wordsize)))))])
(prm 'int+ c (prm 'quotient (T a) b))))] (prm 'int+ c (prm 'int-remainder (T a) b))))]
[(P a b) (K #t)] [(P a b) (K #t)]
[(E a b) (nop)]) [(E a b) (nop)])

View File

@ -1722,12 +1722,15 @@
(let-values (((lhs* rhs* q) (quasi q lev))) (let-values (((lhs* rhs* q) (quasi q lev)))
(if (= lev 0) (if (= lev 0)
(let ((g (gensym))) (let ((g (gensym)))
(values (cons `(,g ...) lhs*) (cons p rhs*) (values
`(,g ... . ,q))) (cons `(,g ...) lhs*)
(cons p rhs*)
`(,g ... . ,q)))
(let-values (((lhs2* rhs2* p) (quasi p (- lev 1)))) (let-values (((lhs2* rhs2* p) (quasi p (- lev 1))))
(values (append lhs2* lhs*) (values
(append rhs2* rhs*) (append lhs2* lhs*)
`((unsyntax-splicing ,p) . ,q)))))) (append rhs2* rhs*)
`((unsyntax-splicing ,p) . ,q))))))
(unsyntax-splicing (= lev 0) (unsyntax-splicing (= lev 0)
(stx-error p "incorrect use of unsyntax-splicing")) (stx-error p "incorrect use of unsyntax-splicing"))
((quasisyntax p) ((quasisyntax p)

View File

@ -40,7 +40,10 @@
(test +3 -7/11) (test +3 -7/11)
(test -3 -7/11) (test -3 -7/11)
(test (least-fixnum) -1)
(test (least-fixnum) 1)
(test (greatest-fixnum) -1)
(test (greatest-fixnum) 1)
) )