(in-package "SB-ROTATE-BYTE") (define-vop (%32bit-rotate-byte/c) (:policy :fast-safe) (:translate %unsigned-32-rotate-byte) (:note "inline 32-bit constant rotation") (:info count) (:args (integer :scs (sb-vm::unsigned-reg) :target res)) (:arg-types (:constant (integer -31 31)) sb-vm::unsigned-byte-32) (:results (res :scs (sb-vm::unsigned-reg))) (:result-types sb-vm::unsigned-byte-32) (:generator 5 ;; the 0 case is an identity operation and should be ;; DEFTRANSFORMed away. (aver (not (= count 0))) (if (> count 0) (inst rotlwi res integer count) (inst rotrwi res integer (- count))))) (define-vop (%32bit-rotate-byte-fixnum/c) (:policy :fast-safe) (:translate %unsigned-32-rotate-byte) (:note "inline 32-bit constant rotation") (:info count) (:args (integer :scs (sb-vm::any-reg) :target res)) (:arg-types (:constant (integer -31 31)) sb-vm::positive-fixnum) (:results (res :scs (sb-vm::unsigned-reg))) (:result-types sb-vm::unsigned-byte-32) (:generator 5 (aver (not (= count 0))) (cond ;; FIXME: all these 2s should be n-fixnum-tag-bits. ((= count 2)) ((> count 2) (inst rotlwi res integer (- count 2))) (t (inst rotrwi res integer (- 2 count)))))) (macrolet ((def (name arg-type) `(define-vop (,name) (:policy :fast-safe) (:translate %unsigned-32-rotate-byte) (:note "inline 32-bit rotation") (:args (count :scs (sb-vm::signed-reg)) (integer :scs (sb-vm::unsigned-reg) :target res)) (:arg-types sb-vm::tagged-num ,arg-type) (:temporary (:scs (sb-vm::unsigned-reg) :from (:argument 0)) realcount) (:results (res :scs (sb-vm::unsigned-reg))) (:result-types sb-vm::unsigned-byte-32) (:generator 10 (let ((label (gen-label)) (end (gen-label))) (inst cmpwi count 0) (inst bge label) (inst addi realcount count 32) (inst rotlw res integer realcount) (inst b end) (emit-label label) (inst rotlw res integer count) (emit-label end)))))) (def %32bit-rotate-byte sb-vm::unsigned-byte-32) ;; FIXME: see x86-vm.lisp (def %32bit-rotate-byte-fixnum sb-vm::positive-fixnum))