fxarithmetic-shift-left now detects overflows properly.
This commit is contained in:
		
							parent
							
								
									97507bce08
								
							
						
					
					
						commit
						85d09cbc1c
					
				
										
											Binary file not shown.
										
									
								
							|  | @ -514,7 +514,7 @@ | |||
|                   (make-asm-instr 'cltd edx eax) | ||||
|                   (make-asm-instr 'idiv edx (cadr rands)) | ||||
|                   (make-set d edx))))] | ||||
|          [(sll sra srl) | ||||
|          [(sll sra srl sll/overflow) | ||||
|           (let ([a (car rands)] [b (cadr rands)]) | ||||
|             (cond | ||||
|               [(constant? b) | ||||
|  | @ -1419,7 +1419,8 @@ | |||
|                       (mark-nfv/frms-conf! d fs) | ||||
|                       (R s vs rs fs (add-nfv d ns)))])] | ||||
|                 [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 | ||||
|             [(var? d)  | ||||
|              (cond | ||||
|  | @ -1665,7 +1666,8 @@ | |||
|               sll sra srl bswap! | ||||
|               cltd idiv int-/overflow int+/overflow int*/overflow | ||||
|               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))] | ||||
|            [(nop) (make-primcall 'nop '())] | ||||
|            [else (error who "invalid op" op)])] | ||||
|  | @ -1888,7 +1890,8 @@ | |||
|             (let ([s (set-rem d (set-union s (exception-live-set)))]) | ||||
|               (set-for-each (lambda (y) (add-edge! g d y)) 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)]) | ||||
|               (set-for-each (lambda (y) (add-edge! g d y)) s) | ||||
|               (set-union (set-union (R v) (R d)) s))] | ||||
|  | @ -2234,7 +2237,7 @@ | |||
|               [(disp? b) | ||||
|                (error who "invalid arg to idiv" b)] | ||||
|               [else x])] | ||||
|            [(sll sra srl) | ||||
|            [(sll sra srl sll/overflow) | ||||
|             (unless (or (constant? b) | ||||
|                         (eq? b ecx)) | ||||
|               (error who "invalid shift" b)) | ||||
|  | @ -2554,6 +2557,12 @@ | |||
|             (cons* `(subl ,(R s) ,(R d))  | ||||
|                    `(jo ,L) | ||||
|                    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) | ||||
|           (let ([L (or (exception-label)  | ||||
|                        (error who "no exception label"))]) | ||||
|  |  | |||
|  | @ -26,7 +26,9 @@ | |||
|           fixnum->string  | ||||
|           fxarithmetic-shift-left fxarithmetic-shift-right fxarithmetic-shift | ||||
|           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  | ||||
|     (ikarus system $fx) | ||||
|     (ikarus system $chars) | ||||
|  | @ -267,16 +269,22 @@ | |||
|         (die 'fxsll "negative shift not allowed" 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 | ||||
|     (lambda (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)) | ||||
|       ($fxsll x y))) | ||||
|       (import (ikarus)) | ||||
|       (fxarithmetic-shift-left x y))) | ||||
| 
 | ||||
|   (define fxarithmetic-shift | ||||
|     (lambda (x y)  | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| 1415 | ||||
| 1416 | ||||
|  |  | |||
|  | @ -568,6 +568,7 @@ | |||
|     [make-promise                                ] | ||||
|     [make-traced-procedure                       i] | ||||
|     [error@fx+                                   ] | ||||
|     [error@fxarithmetic-shift-left               ] | ||||
|     [error@fx*                                   ] | ||||
|     [error@fx-                                   ] | ||||
|     [error@add1                                  ] | ||||
|  |  | |||
|  | @ -1295,6 +1295,42 @@ | |||
|      (cogen-pred-$fxzero? 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)  | ||||
|   (let f ([n n] [i 0]) | ||||
|     (cond | ||||
|  | @ -1303,6 +1339,8 @@ | |||
|       [(= n 1) i] | ||||
|       [else #f]))) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| (define-primop div safe | ||||
|   [(V x n)  | ||||
|    (struct-case n  | ||||
|  |  | |||
|  | @ -55,13 +55,14 @@ | |||
|     (prm 'interrupt)) | ||||
|   (define (primop-interrupt-handler x) | ||||
|     (case x | ||||
|       [(fx+)          'error@fx+] | ||||
|       [(fx-)          'error@fx-] | ||||
|       [(fx*)          'error@fx*] | ||||
|       [(add1)         'error@add1] | ||||
|       [(sub1)         'error@sub1] | ||||
|       [(fxadd1)       'error@fxadd1] | ||||
|       [(fxsub1)       'error@fxsub1] | ||||
|       [(fx+)                     'error@fx+] | ||||
|       [(fx-)                     'error@fx-] | ||||
|       [(fx*)                     'error@fx*] | ||||
|       [(add1)                    'error@add1] | ||||
|       [(sub1)                    'error@sub1] | ||||
|       [(fxadd1)                  'error@fxadd1] | ||||
|       [(fxsub1)                  'error@fxsub1] | ||||
|       [(fxarithmetic-shift-left) 'error@fxarithmetic-shift-left] | ||||
|       [else                    x])) | ||||
|   (define (make-interrupt-call op args) | ||||
|     (make-funcall  | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Abdulaziz Ghuloum
						Abdulaziz Ghuloum