Skip to content

Instantly share code, notes, and snippets.

@privet-kitty
Last active October 9, 2021 01:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save privet-kitty/12d301145803faf175490e33b397fa4e to your computer and use it in GitHub Desktop.
Save privet-kitty/12d301145803faf175490e33b397fa4e to your computer and use it in GitHub Desktop.
(sb-c::defknown modular* ((unsigned-byte 64) (unsigned-byte 64)) (unsigned-byte 64)
(sb-c::movable sb-c::foldable sb-c::flushable sb-c::commutative)
:overwrite-fndb-silently t)
;; same as fast-*/unsigned=>unsigned
(sb-c::define-vop (fast-mult sb-vm::fast-safe-arith-op)
(:translate modular*)
(:args (x :scs (sb-vm::unsigned-reg) :target eax)
(y :scs (sb-vm::unsigned-reg sb-vm::unsigned-stack)))
(:arg-types sb-vm::unsigned-num sb-vm::unsigned-num)
(:temporary (:sc sb-vm::unsigned-reg :offset sb-vm::rax-offset :target r
:from (:argument 0) :to :result) eax)
(:temporary (:sc sb-vm::unsigned-reg :offset sb-vm::rdx-offset
:from :eval :to :result) edx)
(:ignore edx)
(:results (r :scs (sb-vm::unsigned-reg)))
(:result-types sb-vm::unsigned-num)
(:note "inline (unsigned-byte 64) arithmetic")
(:vop-var vop)
(:save-p :compute-only)
(:generator 6
(sb-c:move eax x)
(sb-assem::inst sb-x86-64-asm::mul eax y)
(sb-c:move r eax)))
(defun test1 (n)
(declare (optimize (speed 3) (safety 0))
((integer 0 #.most-positive-fixnum) n))
(let ((res 0))
(declare (bit res))
(dotimes (x n res)
(let ((bit (ldb (byte 1 63) (modular* x (+ 7 (expt 10 15))))))
(setq res (logxor bit res))))))
(disassemble #'test1)
(time (test1 4000000000))
;; same as fast-*-c/unsigned=>unsigned
(sb-c::define-vop (fast-mult-c sb-vm::fast-safe-arith-op)
(:translate modular*)
(:args (x :scs (sb-vm::unsigned-reg) :target eax))
(:info y)
(:arg-types sb-vm::unsigned-num (:constant (unsigned-byte 64)))
(:temporary (:sc sb-vm::unsigned-reg :offset sb-vm::rax-offset :target r
:from (:argument 0) :to :result) eax)
(:temporary (:sc sb-vm::unsigned-reg :offset sb-vm::rdx-offset
:from :eval :to :result) edx)
(:ignore edx)
(:results (r :scs (sb-vm::unsigned-reg)))
(:result-types sb-vm::unsigned-num)
(:note "inline (unsigned-byte 64) arithmetic")
(:vop-var vop)
(:save-p :compute-only)
(:generator
5
(sb-c:move eax x)
(sb-assem::inst sb-x86-64-asm::mul eax (sb-c:register-inline-constant :qword y))
(sb-c:move r eax)))
(defun test2 (n)
(declare (optimize (speed 3) (safety 0))
((integer 0 #.most-positive-fixnum) n))
(let ((res 0))
(declare (bit res))
(dotimes (x n res)
(let ((bit (ldb (byte 1 63) (modular* x (+ 7 (expt 10 15))))))
(setq res (logxor bit res))))))
(disassemble #'test2)
(time (test2 4000000000))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment