X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=contrib%2Fsb-rotate-byte%2Fx86-64-vm.lisp;fp=contrib%2Fsb-rotate-byte%2Fx86-64-vm.lisp;h=d45b5969a5e63af2125d06c33b3ad1ff0bf3df75;hb=4205c4d51cf98324917b1855b9085b21f923b09c;hp=0000000000000000000000000000000000000000;hpb=abc6bed30fe634a0542d5a1424481447ba18386c;p=sbcl.git diff --git a/contrib/sb-rotate-byte/x86-64-vm.lisp b/contrib/sb-rotate-byte/x86-64-vm.lisp new file mode 100644 index 0000000..d45b596 --- /dev/null +++ b/contrib/sb-rotate-byte/x86-64-vm.lisp @@ -0,0 +1,86 @@ +(in-package "SB-ROTATE-BYTE") + + +;;; 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)))) + +;;; 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))))