X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=contrib%2Fsb-rotate-byte%2Fcompiler.lisp;h=58937d6355603f8f8ed864fd5bcfa48a443ff00a;hb=8369a441bfd49566e70939c25f42f8d1f5423e4e;hp=2e7d5e1d7f1bc179613d2cab5aab069bc57458c5;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/contrib/sb-rotate-byte/compiler.lisp b/contrib/sb-rotate-byte/compiler.lisp index 2e7d5e1..58937d6 100644 --- a/contrib/sb-rotate-byte/compiler.lisp +++ b/contrib/sb-rotate-byte/compiler.lisp @@ -7,6 +7,10 @@ (defknown %unsigned-32-rotate-byte ((integer -31 31) (unsigned-byte 32)) (unsigned-byte 32) (foldable flushable)) +#+x86-64 +(defknown %unsigned-64-rotate-byte ((integer -63 63) (unsigned-byte 64)) + (unsigned-byte 64) + (foldable flushable)) (macrolet (;; see src/compiler/srctran.lisp (with-byte-specifier ((size-var pos-var spec) &body body) @@ -43,16 +47,38 @@ *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)) *) "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)