0.7.13.28:
[sbcl.git] / src / code / sxhash.lisp
index 2db5a48..61f4d29 100644 (file)
 ;;; simple.
 (deftransform sxhash ((x) (fixnum))
   '(logand most-positive-fixnum
-          (logxor x
-                  (ash x -3) ; to get sign bit into hash
+          (logxor (ash (logand x (ash most-positive-fixnum -4)) 4) 
+                  (ash x -1) ; to get sign bit into hash
                   361475658)))
 
+;;; SXHASH of SIMPLE-BIT-VECTOR values is defined as a DEFTRANSFORM
+;;; because it is endian-dependent.
+(deftransform sxhash ((x) (simple-bit-vector))
+  `(let ((result 410823708))
+    (declare (type fixnum result))
+    (mixf result (sxhash (length x)))
+    (do* ((i sb!vm:vector-data-offset (+ i 1))
+         ;; FIXME: should we respect DEPTHOID?  SXHASH on strings
+         ;; doesn't seem to...
+         (end (+ sb!vm:vector-data-offset
+                 (ceiling (length x) sb!vm:n-word-bits))))
+        ((= i end) result)
+      (declare (type index i end))
+      (let ((num
+            (if (= i (1- end))
+                (logand
+                 (ash (1- (ash 1 (mod (length x) sb!vm:n-word-bits)))
+                      ,(ecase sb!c:*backend-byte-order*
+                         (:little-endian 0)
+                         (:big-endian
+                          '(- sb!vm:n-word-bits
+                              (mod (length x) sb!vm:n-word-bits)))))
+                 (%raw-bits x i))
+                (%raw-bits x i))))
+       (declare (type (unsigned-byte 32) num))
+       (mixf result ,(ecase sb!c:*backend-byte-order*
+                       (:little-endian '(logand num most-positive-fixnum))
+                       ;; FIXME: I'm not certain that N-LOWTAG-BITS
+                       ;; is the clearest way of expressing this:
+                       ;; it's essentially the difference between
+                       ;; `(UNSIGNED-BYTE ,SB!VM:N-WORD-BITS) and
+                       ;; (AND FIXNUM UNSIGNED-BYTE).
+                       (:big-endian '(ash num (- sb!vm:n-lowtag-bits)))))))))
+
 ;;; Some other common SXHASH cases are defined as DEFTRANSFORMs in
 ;;; order to avoid having to do TYPECASE at runtime.
 ;;;
@@ -59,3 +93,5 @@
   (if #+sb-xc-host nil #-sb-xc-host (constant-continuation-p x)
       (sxhash (continuation-value x))
       '(%sxhash-simple-string (symbol-name x))))
+
+