Fix typos in docstrings and function names.
[sbcl.git] / contrib / sb-rotate-byte / compiler.lisp
index 7165b36..38079fb 100644 (file)
@@ -1,12 +1,20 @@
 (in-package "SB-ROTATE-BYTE")
 
 (defknown rotate-byte (integer byte-specifier integer) integer
-  (foldable flushable))
+  (foldable flushable)
+  :overwrite-fndb-silently t)
 (defknown %rotate-byte (integer bit-index bit-index integer) integer
-  (foldable flushable))
+  (foldable flushable)
+  :overwrite-fndb-silently t)
 (defknown %unsigned-32-rotate-byte ((integer -31 31) (unsigned-byte 32))
     (unsigned-byte 32)
-  (foldable flushable))
+  (foldable flushable)
+  :overwrite-fndb-silently t)
+#+x86-64
+(defknown %unsigned-64-rotate-byte ((integer -63 63) (unsigned-byte 64))
+    (unsigned-byte 64)
+  (foldable flushable)
+  :overwrite-fndb-silently t)
 
 (macrolet (;; see src/compiler/srctran.lisp
            (with-byte-specifier ((size-var pos-var spec) &body body)
   ;; simpler, and also be made to deal with negative integers too.
   (let ((size (sb-c::lvar-type size)))
     (if (numeric-type-p size)
-       (let ((size-high (numeric-type-high size))
-             (num-type (sb-c::lvar-type num)))
-         (if (and size-high
-                  num-type
-                  (<= size-high sb-vm:n-word-bits)
-                  (csubtypep num-type
-                             (specifier-type `(unsigned-byte ,size-high))))
+        (let ((size-high (numeric-type-high size))
+              (num-type (sb-c::lvar-type num)))
+          (if (and size-high
+                   num-type
+                   (<= size-high sb-vm:n-word-bits)
+                   (csubtypep num-type
+                              (specifier-type `(unsigned-byte ,size-high))))
               (specifier-type `(unsigned-byte ,size-high))
-             *universal-type*))
+              *universal-type*))
         *universal-type*)))
 
 (deftransform %rotate-byte ((count size pos integer)
-                           ((constant-arg (member 0)) * * *) *)
-  "fold identity operation"
-  'integer)
-
-(deftransform %rotate-byte ((count size pos integer)
-                           ((integer -31 31)
-                            (constant-arg (member 32))
-                            (constant-arg (member 0))
-                            (unsigned-byte 32)) *)
+                            ((integer -31 31)
+                             (constant-arg (member 32))
+                             (constant-arg (member 0))
+                             (unsigned-byte 32)) *)
   "inline 32-bit rotation"
-  ;; FIXME: What happens when, as here, the two type specifiers for
-  ;; COUNT overlap?  Which gets to run first?
   '(%unsigned-32-rotate-byte count integer))
+
+;; Generic implementation for platforms that don't supply VOPs for 32-bit
+;; rotate.
+#-(or x86 x86-64 ppc)
+(deftransform %unsigned-32-rotate-byte ((.count. .integer.)
+                                        ((integer -31 31)
+                                         (unsigned-byte 32)) *)
+  '(if (< .count. 0)
+       (logior (ldb (byte 32 0) (ash .integer. (+ .count. 32)))
+               (ash .integer. .count.))
+       (logior (ldb (byte 32 0) (ash .integer. .count.))
+               (ash .integer. (- .count. 32)))))
+
+#+x86-64
+(deftransform %rotate-byte ((count size pos integer)
+                            ((integer -63 63)
+                             (constant-arg (member 64))
+                             (constant-arg (member 0))
+                             (unsigned-byte 64)) *)
+  "inline 64-bit rotation"
+  '(%unsigned-64-rotate-byte count integer))
+
+;;; This transform needs to come after the others to ensure it gets
+;;; first crack at a zero COUNT, since transforms are currently run
+;;; latest-defined first.
+(deftransform %rotate-byte ((count size pos integer)
+                            ((constant-arg (member 0)) * * *) *)
+  "fold identity operation"
+  'integer)