fixed a bug in quotient and div when given (least-fixnum) and -1.
This commit is contained in:
parent
4909a9ef08
commit
3b80d4f321
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1553
|
1554
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)])
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue