--- /dev/null
+(in-package "SB-ROTATE-BYTE")
+
+\f
+;;; 32-bit rotates
+
+(define-vop (%32bit-rotate-byte/c)
+ (:policy :fast-safe)
+ (:translate %unsigned-32-rotate-byte)
+ (:note "inline 32-bit constant rotation")
+ (:args (integer :scs (sb-vm::unsigned-reg) :target result))
+ (:info count)
+ (:arg-types (:constant (integer -31 31)) sb-vm::unsigned-num)
+ (:results (result :scs (sb-vm::unsigned-reg)))
+ (:result-types sb-vm::unsigned-num)
+ (:generator 5
+ (aver (not (= count 0)))
+ (move result integer)
+ (if (> count 0)
+ (inst rol (sb-vm::reg-in-size result :dword) count)
+ (inst ror (sb-vm::reg-in-size result :dword) count))))
+
+(define-vop (%32bit-rotate-byte)
+ (:policy :fast-safe)
+ (:translate %unsigned-32-rotate-byte)
+ (:args (count :scs (sb-vm::signed-reg) :target rcx)
+ (integer :scs (sb-vm::unsigned-reg) :target result))
+ (:arg-types sb-vm::tagged-num sb-vm::unsigned-num)
+ (:temporary (:sc sb-vm::signed-reg :offset sb-vm::rcx-offset)
+ rcx)
+ (:results (result :scs (sb-vm::unsigned-reg) :from :load))
+ (:result-types sb-vm::unsigned-num)
+ (:generator 10
+ (let ((label (gen-label))
+ (end (gen-label)))
+ (move result integer)
+ (move rcx count)
+ (inst cmp (sb-vm::reg-in-size rcx :dword) 0)
+ (inst jmp :ge label)
+ (inst neg (sb-vm::reg-in-size rcx :dword))
+ (inst ror (sb-vm::reg-in-size result :dword) :cl)
+ (inst jmp end)
+ (emit-label label)
+ (inst rol (sb-vm::reg-in-size result :dword) :cl)
+ (emit-label end))))
+\f
+;;; 64-bit rotates
+
+(define-vop (%64bit-rotate-byte/c)
+ (:policy :fast-safe)
+ (:translate %unsigned-64-rotate-byte)
+ (:note "inline 64-bit constant rotation")
+ (:args (integer :scs (sb-vm::unsigned-reg) :target result))
+ (:info count)
+ (:arg-types (:constant (integer -63 63)) sb-vm::unsigned-num)
+ (:results (result :scs (sb-vm::unsigned-reg)))
+ (:result-types sb-vm::unsigned-num)
+ (:generator 5
+ (aver (not (= count 0)))
+ (move result integer)
+ (if (> count 0)
+ (inst rol result count)
+ (inst ror result count))))
+
+(define-vop (%64bit-rotate-byte)
+ (:policy :fast-safe)
+ (:translate %unsigned-64-rotate-byte)
+ (:args (count :scs (sb-vm::signed-reg) :target rcx)
+ (integer :scs (sb-vm::unsigned-reg) :target result))
+ (:arg-types sb-vm::tagged-num sb-vm::unsigned-num)
+ (:temporary (:sc sb-vm::signed-reg :offset sb-vm::rcx-offset)
+ rcx)
+ (:results (result :scs (sb-vm::unsigned-reg) :from :load))
+ (:result-types sb-vm::unsigned-num)
+ (:generator 10
+ (let ((label (gen-label))
+ (end (gen-label)))
+ (move result integer)
+ (move rcx count)
+ (inst cmp rcx 0)
+ (inst jmp :ge label)
+ (inst neg rcx)
+ (inst ror result :cl)
+ (inst jmp end)
+ (emit-label label)
+ (inst rol result :cl)
+ (emit-label end))))