fxarithmetic-shift-left now detects overflows properly.

This commit is contained in:
Abdulaziz Ghuloum 2008-03-18 00:49:24 -04:00
parent 97507bce08
commit 85d09cbc1c
7 changed files with 78 additions and 21 deletions

Binary file not shown.

View File

@ -514,7 +514,7 @@
(make-asm-instr 'cltd edx eax) (make-asm-instr 'cltd edx eax)
(make-asm-instr 'idiv edx (cadr rands)) (make-asm-instr 'idiv edx (cadr rands))
(make-set d edx))))] (make-set d edx))))]
[(sll sra srl) [(sll sra srl sll/overflow)
(let ([a (car rands)] [b (cadr rands)]) (let ([a (car rands)] [b (cadr rands)])
(cond (cond
[(constant? b) [(constant? b)
@ -1419,7 +1419,8 @@
(mark-nfv/frms-conf! d fs) (mark-nfv/frms-conf! d fs)
(R s vs rs fs (add-nfv d ns)))])] (R s vs rs fs (add-nfv d ns)))])]
[else (error who "invalid op d" (unparse x))])))] [else (error who "invalid op d" (unparse x))])))]
[(logand logor logxor sll sra srl int+ int- int* bswap!) [(logand logor logxor sll sra srl int+ int- int* bswap!
sll/overflow)
(cond (cond
[(var? d) [(var? d)
(cond (cond
@ -1665,7 +1666,8 @@
sll sra srl bswap! sll sra srl bswap!
cltd idiv int-/overflow int+/overflow int*/overflow cltd idiv int-/overflow int+/overflow int*/overflow
fl:load fl:store fl:add! fl:sub! fl:mul! fl:div! fl:load fl:store fl:add! fl:sub! fl:mul! fl:div!
fl:from-int fl:shuffle fl:load-single fl:store-single) fl:from-int fl:shuffle fl:load-single fl:store-single
sll/overflow)
(make-asm-instr op (R d) (R s))] (make-asm-instr op (R d) (R s))]
[(nop) (make-primcall 'nop '())] [(nop) (make-primcall 'nop '())]
[else (error who "invalid op" op)])] [else (error who "invalid op" op)])]
@ -1888,7 +1890,8 @@
(let ([s (set-rem d (set-union s (exception-live-set)))]) (let ([s (set-rem d (set-union s (exception-live-set)))])
(set-for-each (lambda (y) (add-edge! g d y)) s) (set-for-each (lambda (y) (add-edge! g d y)) s)
(set-union (set-union (R v) (R d)) s))] (set-union (set-union (R v) (R d)) s))]
[(logand logxor int+ int- int* logor sll sra srl bswap!) [(logand logxor int+ int- int* logor sll sra srl bswap!
sll/overflow)
(let ([s (set-rem d s)]) (let ([s (set-rem d s)])
(set-for-each (lambda (y) (add-edge! g d y)) s) (set-for-each (lambda (y) (add-edge! g d y)) s)
(set-union (set-union (R v) (R d)) s))] (set-union (set-union (R v) (R d)) s))]
@ -2234,7 +2237,7 @@
[(disp? b) [(disp? b)
(error who "invalid arg to idiv" b)] (error who "invalid arg to idiv" b)]
[else x])] [else x])]
[(sll sra srl) [(sll sra srl sll/overflow)
(unless (or (constant? b) (unless (or (constant? b)
(eq? b ecx)) (eq? b ecx))
(error who "invalid shift" b)) (error who "invalid shift" b))
@ -2554,6 +2557,12 @@
(cons* `(subl ,(R s) ,(R d)) (cons* `(subl ,(R s) ,(R d))
`(jo ,L) `(jo ,L)
ac))] ac))]
[(sll/overflow)
(let ([L (or (exception-label)
(error who "no exception label"))])
(cons* `(sall ,(R/cl s) ,(R d))
`(jo ,L)
ac))]
[(int*/overflow) [(int*/overflow)
(let ([L (or (exception-label) (let ([L (or (exception-label)
(error who "no exception label"))]) (error who "no exception label"))])

View File

@ -26,7 +26,9 @@
fixnum->string fixnum->string
fxarithmetic-shift-left fxarithmetic-shift-right fxarithmetic-shift fxarithmetic-shift-left fxarithmetic-shift-right fxarithmetic-shift
fxmin fxmax fxmin fxmax
error@fx+ error@fx* error@fx- error@fxadd1 error@fxsub1) error@fx+ error@fx* error@fx- error@fxadd1 error@fxsub1
error@fxarithmetic-shift-left
)
(import (import
(ikarus system $fx) (ikarus system $fx)
(ikarus system $chars) (ikarus system $chars)
@ -267,16 +269,22 @@
(die 'fxsll "negative shift not allowed" y)) (die 'fxsll "negative shift not allowed" y))
($fxsll x y))) ($fxsll x y)))
(define (error@fxarithmetic-shift-left x y)
(unless (fixnum? x)
(die 'fxarithmetic-shift-left "not a fixnum" x))
(unless (fixnum? y)
(die 'fxarithmetic-shift-left "not a fixnum" y))
(unless ($fx>= y 0)
(die 'fxarithmetic-shift-left "negative shift not allowed" y))
(unless ($fx< y (fixnum-width))
(die 'fxarithmetic-shift-left
"shift is not less than fixnum-width" y))
(die 'fxarithmetic-shift-left "overflow" x y))
(define fxarithmetic-shift-left (define fxarithmetic-shift-left
(lambda (x y) (lambda (x y)
(unless (fixnum? x) (import (ikarus))
(die 'fxarithmetic-shift-left "not a fixnum" x)) (fxarithmetic-shift-left x y)))
(unless (fixnum? y)
(die 'fxarithmetic-shift-left "not a fixnum" y))
(unless ($fx>= y 0)
(die 'fxarithmetic-shift-left "negative shift not allowed" y))
($fxsll x y)))
(define fxarithmetic-shift (define fxarithmetic-shift
(lambda (x y) (lambda (x y)

View File

@ -1 +1 @@
1415 1416

View File

@ -568,6 +568,7 @@
[make-promise ] [make-promise ]
[make-traced-procedure i] [make-traced-procedure i]
[error@fx+ ] [error@fx+ ]
[error@fxarithmetic-shift-left ]
[error@fx* ] [error@fx* ]
[error@fx- ] [error@fx- ]
[error@add1 ] [error@add1 ]

View File

@ -1295,6 +1295,42 @@
(cogen-pred-$fxzero? x))] (cogen-pred-$fxzero? x))]
[(E x) (interrupt-unless (cogen-pred-fixnum? x))]) [(E x) (interrupt-unless (cogen-pred-fixnum? x))])
(define-primop fxarithmetic-shift-left safe
[(V x n)
(struct-case n
[(constant i)
(cond
[(and (fixnum? i)
(>= i 0)
(< i (- (* wordsize 8) fx-shift)))
(with-tmp ([x (T x)])
(assert-fixnum x)
(cond
[(< i 6)
(let f ([i i])
(cond
[(zero? i) x]
[else (prm 'sll/overflow (f (- i 1)) (K 1))]))]
[else
(with-tmp ([x2 (prm 'sll x (K i))])
(interrupt-unless (prm '= (prm 'sra x2 (K i)) x))
x2)]))]
[else
(interrupt)])]
[else
(with-tmp ([x (T x)] [n (T n)])
(assert-fixnums x (list n))
(with-tmp ([n (prm 'sra n (K fx-shift))])
(interrupt-when
(prm '< n (K 0)))
(interrupt-when
(prm '>= n (K (- (* wordsize 8) fx-shift))))
(with-tmp ([x2 (prm 'sll x n)])
(interrupt-unless (prm '= (prm 'sra x2 n) x))
x2)))])])
(define (log2 n) (define (log2 n)
(let f ([n n] [i 0]) (let f ([n n] [i 0])
(cond (cond
@ -1303,6 +1339,8 @@
[(= n 1) i] [(= n 1) i]
[else #f]))) [else #f])))
(define-primop div safe (define-primop div safe
[(V x n) [(V x n)
(struct-case n (struct-case n

View File

@ -55,13 +55,14 @@
(prm 'interrupt)) (prm 'interrupt))
(define (primop-interrupt-handler x) (define (primop-interrupt-handler x)
(case x (case x
[(fx+) 'error@fx+] [(fx+) 'error@fx+]
[(fx-) 'error@fx-] [(fx-) 'error@fx-]
[(fx*) 'error@fx*] [(fx*) 'error@fx*]
[(add1) 'error@add1] [(add1) 'error@add1]
[(sub1) 'error@sub1] [(sub1) 'error@sub1]
[(fxadd1) 'error@fxadd1] [(fxadd1) 'error@fxadd1]
[(fxsub1) 'error@fxsub1] [(fxsub1) 'error@fxsub1]
[(fxarithmetic-shift-left) 'error@fxarithmetic-shift-left]
[else x])) [else x]))
(define (make-interrupt-call op args) (define (make-interrupt-call op args)
(make-funcall (make-funcall