X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fgeneric%2Fvm-tran.lisp;h=7866594e0405dc96ed38c501903e0606a083b56b;hb=ca267caa3bdb897a93a1e69ae7300ba3ba5d391f;hp=6a3e942a15f7477ced00dc15a884e97d2061badb;hpb=1ca02b016cddad0800852a9d8fe7a3cb6cc7a01d;p=sbcl.git diff --git a/src/compiler/generic/vm-tran.lisp b/src/compiler/generic/vm-tran.lisp index 6a3e942..7866594 100644 --- a/src/compiler/generic/vm-tran.lisp +++ b/src/compiler/generic/vm-tran.lisp @@ -36,6 +36,7 @@ ;;;; character support ;;; In our implementation there are really only BASE-CHARs. +#+nil (define-source-transform characterp (obj) `(base-char-p ,obj)) @@ -48,6 +49,8 @@ (give-up-ir1-transform) `(etypecase string ((simple-array character (*)) (data-vector-ref string index)) + #!+sb-unicode + ((simple-array base-char (*)) (data-vector-ref string index)) ((simple-array nil (*)) (data-vector-ref string index)))))) (deftransform hairy-data-vector-ref ((array index) (array t) *) @@ -98,6 +101,9 @@ `(etypecase string ((simple-array character (*)) (data-vector-set string index new-value)) + #!+sb-unicode + ((simple-array base-char (*)) + (data-vector-set string index new-value)) ((simple-array nil (*)) (data-vector-set string index new-value)))))) @@ -228,7 +234,7 @@ (length bit-array-2) (length result-bit-array)) (error "Argument and/or result bit arrays are not the same length:~ - ~% ~S~% ~S ~% ~S" + ~% ~S~% ~S ~% ~S" bit-array-1 bit-array-2 result-bit-array)))) @@ -278,20 +284,20 @@ '((unless (= (length bit-array) (length result-bit-array)) (error "Argument and result bit arrays are not the same length:~ - ~% ~S~% ~S" + ~% ~S~% ~S" bit-array result-bit-array)))) (let ((length (length result-bit-array))) (if (= length 0) - ;; We avoid doing anything to 0-length bit-vectors, or - ;; rather, the memory that follows them. Other - ;; divisible-by-32 cases are handled by the (1- length), - ;; below. CSR, 2002-04-24 + ;; We avoid doing anything to 0-length bit-vectors, or rather, + ;; the memory that follows them. Other divisible-by + ;; n-word-bits cases are handled by the (1- length), below. + ;; CSR, 2002-04-24 result-bit-array (do ((index sb!vm:vector-data-offset (1+ index)) (end-1 (+ sb!vm:vector-data-offset - ;; bit-vectors of length 1-32 need precisely - ;; one (SETF %RAW-BITS), done here in the - ;; epilogue. - CSR, 2002-04-24 + ;; bit-vectors of length 1 to n-word-bits need + ;; precisely one (SETF %RAW-BITS), done here in + ;; the epilogue. - CSR, 2002-04-24 (truncate (truly-the index (1- length)) sb!vm:n-word-bits)))) ((= index end-1) @@ -311,7 +317,7 @@ (end-1 (+ sb!vm:vector-data-offset (floor (1- length) sb!vm:n-word-bits)))) ((= i end-1) - (let* ((extra (mod length sb!vm:n-word-bits)) + (let* ((extra (1+ (mod (1- length) sb!vm:n-word-bits))) (mask (1- (ash 1 extra))) (numx (logand @@ -329,7 +335,7 @@ (:big-endian '(- sb!vm:n-word-bits extra)))) (%raw-bits y i)))) - (declare (type (integer 0 31) extra) + (declare (type (integer 1 #.sb!vm:n-word-bits) extra) (type sb!vm:word mask numx numy)) (= numx numy))) (declare (type index i end-1)) @@ -339,7 +345,7 @@ (unless (= numx numy) (return nil)))))))) -(deftransform count ((sequence item) (simple-bit-vector bit) * +(deftransform count ((item sequence) (bit simple-bit-vector) * :policy (>= speed space)) `(let ((length (length sequence))) (if (zerop length) @@ -350,7 +356,7 @@ (truncate (truly-the index (1- length)) sb!vm:n-word-bits)))) ((= index end-1) - (let* ((extra (mod length sb!vm:n-word-bits)) + (let* ((extra (1+ (mod (1- length) sb!vm:n-word-bits))) (mask (1- (ash 1 extra))) (bits (logand (ash mask ,(ecase sb!c:*backend-byte-order* @@ -358,6 +364,7 @@ (:big-endian '(- sb!vm:n-word-bits extra)))) (%raw-bits sequence index)))) + (declare (type (integer 1 #.sb!vm:n-word-bits) extra)) (declare (type sb!vm:word mask bits)) ;; could consider LOGNOT for the zero case instead of ;; doing the subtraction... @@ -383,17 +390,17 @@ (let ((value (if (constant-lvar-p item) (if (= (lvar-value item) 0) 0 - #.(1- (ash 1 32))) - `(if (= item 0) 0 #.(1- (ash 1 32)))))) + #.(1- (ash 1 sb!vm:n-word-bits))) + `(if (= item 0) 0 #.(1- (ash 1 sb!vm:n-word-bits)))))) `(let ((length (length sequence)) (value ,value)) (if (= length 0) sequence (do ((index sb!vm:vector-data-offset (1+ index)) (end-1 (+ sb!vm:vector-data-offset - ;; bit-vectors of length 1-32 need precisely - ;; one (SETF %RAW-BITS), done here in the - ;; epilogue. - CSR, 2002-04-24 + ;; bit-vectors of length 1 to n-word-bits need + ;; precisely one (SETF %RAW-BITS), done here + ;; in the epilogue. - CSR, 2002-04-24 (truncate (truly-the index (1- length)) sb!vm:n-word-bits)))) ((= index end-1) @@ -407,18 +414,21 @@ :policy (>= speed space)) (let ((value (if (constant-lvar-p item) (let* ((char (lvar-value item)) - (code (sb!xc:char-code char))) - (logior code (ash code 8) (ash code 16) (ash code 24))) + (code (sb!xc:char-code char)) + (accum 0)) + (dotimes (i sb!vm:n-word-bytes accum) + (setf accum (logior accum (ash code (* 8 i)))))) `(let ((code (sb!xc:char-code item))) - (logior code (ash code 8) (ash code 16) (ash code 24)))))) + (logior ,@(loop for i from 0 below sb!vm:n-word-bytes + collect `(ash code ,(* 8 i)))))))) `(let ((length (length sequence)) (value ,value)) (multiple-value-bind (times rem) - (truncate length 4) + (truncate length sb!vm:n-word-bytes) (do ((index sb!vm:vector-data-offset (1+ index)) (end (+ times sb!vm:vector-data-offset))) ((= index end) - (let ((place (* times 4))) + (let ((place (* times sb!vm:n-word-bytes))) (declare (fixnum place)) (dotimes (j rem sequence) (declare (index j)) @@ -477,26 +487,39 @@ ;;;; modular functions -(define-good-modular-fun logand) -(define-good-modular-fun logior) +(define-good-modular-fun logand :unsigned) +(define-good-modular-fun logior :unsigned) ;;; FIXME: XOR? ANDC1, ANDC2? -- CSR, 2003-09-16 (macrolet - ((def (name width) + ((def (name class width) + (let ((type (ecase class + (:unsigned 'unsigned-byte) + (:signed 'signed-byte)))) `(progn - (defknown ,name (integer (integer 0)) (unsigned-byte ,width) + (defknown ,name (integer (integer 0)) (,type ,width) (foldable flushable movable)) - (define-modular-fun-optimizer ash ((integer count) :width width) + (define-modular-fun-optimizer ash ((integer count) ,class :width width) (when (and (<= width ,width) - (constant-lvar-p count) ;? - (plusp (lvar-value count))) - (cut-to-width integer width) + (or (and (constant-lvar-p count) + (plusp (lvar-value count))) + (csubtypep (lvar-type count) + (specifier-type '(and unsigned-byte fixnum))))) + (cut-to-width integer ,class width) ',name)) - (setf (gethash ',name *modular-versions*) `(ash ,',width))))) - #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or)) - (def sb!vm::ash-left-mod32 32) - #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or)) - (def sb!vm::ash-left-mod64 64)) + (setf (gethash ',name (modular-class-versions (find-modular-class ',class))) + `(ash ,',width)))))) + ;; This should really be dependent on SB!VM:N-WORD-BITS, but since we + ;; don't have a true Alpha64 port yet, we'll have to stick to + ;; SB!VM:N-MACHINE-WORD-BITS for the time being. --njf, 2004-08-14 + #!+#.(cl:if (cl:= 32 sb!vm:n-machine-word-bits) '(and) '(or)) + (progn + #!+x86 (def sb!vm::ash-left-smod30 :signed 30) + (def sb!vm::ash-left-mod32 :unsigned 32)) + #!+#.(cl:if (cl:= 64 sb!vm:n-machine-word-bits) '(and) '(or)) + (progn + #!+x86-64 (def sb!vm::ash-left-smod61 :signed 61) + (def sb!vm::ash-left-mod64 :unsigned 64))) ;;;; word-wise logical operations @@ -505,7 +528,7 @@ ;;; generate efficient code. (define-source-transform word-logical-not (x) - `(logand (lognot (the sb!vm:word ,x) #.(1- (ash 1 sb!vm:n-word-bits))))) + `(logand (lognot (the sb!vm:word ,x)) #.(1- (ash 1 sb!vm:n-word-bits)))) (deftransform word-logical-and ((x y)) '(logand x y))