X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=contrib%2Fsb-rotate-byte%2Fcompiler.lisp;h=38079fb1b02e09779254e050231f51c498d62f93;hb=54da325f13fb41669869aea688ae195426c0e231;hp=95dcf655fa39a1d8485944631b39852bbbdcf3ef;hpb=cec71f1e4e1ead387f2ea642f760e553b6053f2b;p=sbcl.git diff --git a/contrib/sb-rotate-byte/compiler.lisp b/contrib/sb-rotate-byte/compiler.lisp index 95dcf65..38079fb 100644 --- a/contrib/sb-rotate-byte/compiler.lisp +++ b/contrib/sb-rotate-byte/compiler.lisp @@ -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) @@ -29,28 +37,52 @@ (defoptimizer (%rotate-byte derive-type) ((count size posn num)) ;; FIXME: this looks fairly unwieldy. I'm sure it can be made ;; simpler, and also be made to deal with negative integers too. - (let ((size (sb-c::continuation-type size))) + (let ((size (sb-c::lvar-type size))) (if (numeric-type-p size) - (let ((size-high (numeric-type-high size)) - (num-type (sb-c::continuation-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) - ((or (integer -31 -1) (integer 1 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" '(%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)