📄 arith.lisp
字号:
(inst lea r (make-ea :qword :base x :disp y))) (t (move r x) (if (= y 1) (inst inc r) (inst add r y))))));;;; multiplication and division(define-vop (fast-*/fixnum=>fixnum fast-safe-arith-op) (:translate *) ;; We need different loading characteristics. (:args (x :scs (any-reg) :target r) (y :scs (any-reg control-stack))) (:arg-types tagged-num tagged-num) (:results (r :scs (any-reg) :from (:argument 0))) (:result-types tagged-num) (:note "inline fixnum arithmetic") (:generator 4 (move r x) (inst sar r 3) (inst imul r y)))(define-vop (fast-*-c/fixnum=>fixnum fast-safe-arith-op) (:translate *) ;; We need different loading characteristics. (:args (x :scs (any-reg control-stack))) (:info y) (:arg-types tagged-num (:constant (signed-byte 29))) (:results (r :scs (any-reg))) (:result-types tagged-num) (:note "inline fixnum arithmetic") (:generator 3 (inst imul r x y)))(define-vop (fast-*/signed=>signed fast-safe-arith-op) (:translate *) ;; We need different loading characteristics. (:args (x :scs (signed-reg) :target r) (y :scs (signed-reg signed-stack))) (:arg-types signed-num signed-num) (:results (r :scs (signed-reg) :from (:argument 0))) (:result-types signed-num) (:note "inline (signed-byte 64) arithmetic") (:generator 5 (move r x) (inst imul r y)))(define-vop (fast-*-c/signed=>signed fast-safe-arith-op) (:translate *) ;; We need different loading characteristics. (:args (x :scs (signed-reg signed-stack))) (:info y) (:arg-types signed-num (:constant (signed-byte 32))) (:results (r :scs (signed-reg))) (:result-types signed-num) (:note "inline (signed-byte 64) arithmetic") (:generator 4 (inst imul r x y)))(define-vop (fast-*/unsigned=>unsigned fast-safe-arith-op) (:translate *) (:args (x :scs (unsigned-reg) :target eax) (y :scs (unsigned-reg unsigned-stack))) (:arg-types unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :target r :from (:argument 0) :to :result) eax) (:temporary (:sc unsigned-reg :offset edx-offset :from :eval :to :result) edx) (:ignore edx) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:note "inline (unsigned-byte 64) arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 6 (move eax x) (inst mul eax y) (move r eax)))(define-vop (fast-truncate/fixnum=>fixnum fast-safe-arith-op) (:translate truncate) (:args (x :scs (any-reg) :target eax) (y :scs (any-reg control-stack))) (:arg-types tagged-num tagged-num) (:temporary (:sc signed-reg :offset eax-offset :target quo :from (:argument 0) :to (:result 0)) eax) (:temporary (:sc unsigned-reg :offset edx-offset :target rem :from (:argument 0) :to (:result 1)) edx) (:results (quo :scs (any-reg)) (rem :scs (any-reg))) (:result-types tagged-num tagged-num) (:note "inline fixnum arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 31 (let ((zero (generate-error-code vop 'division-by-zero-error x y))) (if (sc-is y any-reg) (inst test y y) ; smaller instruction (inst cmp y 0)) (inst jmp :eq zero)) (move eax x) (inst cqo) (inst idiv eax y) (if (location= quo eax) (inst shl eax 3) (inst lea quo (make-ea :qword :index eax :scale 8))) (move rem edx)))(define-vop (fast-truncate-c/fixnum=>fixnum fast-safe-arith-op) (:translate truncate) (:args (x :scs (any-reg) :target eax)) (:info y) (:arg-types tagged-num (:constant (signed-byte 29))) (:temporary (:sc signed-reg :offset eax-offset :target quo :from :argument :to (:result 0)) eax) (:temporary (:sc any-reg :offset edx-offset :target rem :from :eval :to (:result 1)) edx) (:temporary (:sc any-reg :from :eval :to :result) y-arg) (:results (quo :scs (any-reg)) (rem :scs (any-reg))) (:result-types tagged-num tagged-num) (:note "inline fixnum arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 30 (move eax x) (inst cqo) (inst mov y-arg (fixnumize y)) (inst idiv eax y-arg) (if (location= quo eax) (inst shl eax 3) (inst lea quo (make-ea :qword :index eax :scale 8))) (move rem edx)))(define-vop (fast-truncate/unsigned=>unsigned fast-safe-arith-op) (:translate truncate) (:args (x :scs (unsigned-reg) :target eax) (y :scs (unsigned-reg signed-stack))) (:arg-types unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :target quo :from (:argument 0) :to (:result 0)) eax) (:temporary (:sc unsigned-reg :offset edx-offset :target rem :from (:argument 0) :to (:result 1)) edx) (:results (quo :scs (unsigned-reg)) (rem :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:note "inline (unsigned-byte 64) arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 33 (let ((zero (generate-error-code vop 'division-by-zero-error x y))) (if (sc-is y unsigned-reg) (inst test y y) ; smaller instruction (inst cmp y 0)) (inst jmp :eq zero)) (move eax x) (inst xor edx edx) (inst div eax y) (move quo eax) (move rem edx)))(define-vop (fast-truncate-c/unsigned=>unsigned fast-safe-arith-op) (:translate truncate) (:args (x :scs (unsigned-reg) :target eax)) (:info y) (:arg-types unsigned-num (:constant (unsigned-byte 31))) (:temporary (:sc unsigned-reg :offset eax-offset :target quo :from :argument :to (:result 0)) eax) (:temporary (:sc unsigned-reg :offset edx-offset :target rem :from :eval :to (:result 1)) edx) (:temporary (:sc unsigned-reg :from :eval :to :result) y-arg) (:results (quo :scs (unsigned-reg)) (rem :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:note "inline (unsigned-byte 64) arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 32 (move eax x) (inst xor edx edx) (inst mov y-arg y) (inst div eax y-arg) (move quo eax) (move rem edx)))(define-vop (fast-truncate/signed=>signed fast-safe-arith-op) (:translate truncate) (:args (x :scs (signed-reg) :target eax) (y :scs (signed-reg signed-stack))) (:arg-types signed-num signed-num) (:temporary (:sc signed-reg :offset eax-offset :target quo :from (:argument 0) :to (:result 0)) eax) (:temporary (:sc signed-reg :offset edx-offset :target rem :from (:argument 0) :to (:result 1)) edx) (:results (quo :scs (signed-reg)) (rem :scs (signed-reg))) (:result-types signed-num signed-num) (:note "inline (signed-byte 64) arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 33 (let ((zero (generate-error-code vop 'division-by-zero-error x y))) (if (sc-is y signed-reg) (inst test y y) ; smaller instruction (inst cmp y 0)) (inst jmp :eq zero)) (move eax x) (inst cqo) (inst idiv eax y) (move quo eax) (move rem edx)))(define-vop (fast-truncate-c/signed=>signed fast-safe-arith-op) (:translate truncate) (:args (x :scs (signed-reg) :target eax)) (:info y) (:arg-types signed-num (:constant (signed-byte 32))) (:temporary (:sc signed-reg :offset eax-offset :target quo :from :argument :to (:result 0)) eax) (:temporary (:sc signed-reg :offset edx-offset :target rem :from :eval :to (:result 1)) edx) (:temporary (:sc signed-reg :from :eval :to :result) y-arg) (:results (quo :scs (signed-reg)) (rem :scs (signed-reg))) (:result-types signed-num signed-num) (:note "inline (signed-byte 64) arithmetic") (:vop-var vop) (:save-p :compute-only) (:generator 32 (move eax x) (inst cqo) (inst mov y-arg y) (inst idiv eax y-arg) (move quo eax) (move rem edx)));;;; Shifting(define-vop (fast-ash-c/fixnum=>fixnum) (:translate ash) (:policy :fast-safe) (:args (number :scs (any-reg) :target result :load-if (not (and (sc-is number any-reg control-stack) (sc-is result any-reg control-stack) (location= number result))))) (:info amount) (:arg-types tagged-num (:constant integer)) (:results (result :scs (any-reg) :load-if (not (and (sc-is number control-stack) (sc-is result control-stack) (location= number result))))) (:result-types tagged-num) (:note "inline ASH") (:generator 2 (cond ((and (= amount 1) (not (location= number result))) (inst lea result (make-ea :qword :base number :index number))) ((and (= amount 2) (not (location= number result))) (inst lea result (make-ea :qword :index number :scale 4))) ((and (= amount 3) (not (location= number result))) (inst lea result (make-ea :qword :index number :scale 8))) (t (move result number) (cond ((< -64 amount 64) ;; this code is used both in ASH and ASH-SMOD61, so ;; be careful (if (plusp amount) (inst shl result amount) (progn (inst sar result (- amount)) (inst and result (lognot fixnum-tag-mask))))) ((plusp amount) (if (sc-is result any-reg) (inst xor result result) (inst mov result 0))) (t (inst sar result 63) (inst and result (lognot fixnum-tag-mask))))))))(define-vop (fast-ash-left/fixnum=>fixnum) (:translate ash) (:args (number :scs (any-reg) :target result :load-if (not (and (sc-is number control-stack) (sc-is result control-stack) (location= number result)))) (amount :scs (unsigned-reg) :target ecx)) (:arg-types tagged-num positive-fixnum) (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx) (:results (result :scs (any-reg) :from (:argument 0) :load-if (not (and (sc-is number control-stack) (sc-is result control-stack) (location= number result))))) (:result-types tagged-num) (:policy :fast-safe) (:note "inline ASH") (:generator 3 (move result number) (move ecx amount) ;; The result-type ensures us that this shift will not overflow. (inst shl result :cl)))(define-vop (fast-ash-c/signed=>signed) (:translate ash) (:policy :fast-safe) (:args (number :scs (signed-reg) :target result :load-if (not (and (sc-is number signed-stack) (sc-is result signed-stack) (location= number result))))) (:info amount) (:arg-types signed-num (:constant integer)) (:results (result :scs (signed-reg) :load-if (not (and (sc-is number signed-stack) (sc-is result signed-stack) (location= number result))))) (:result-types signed-num) (:note "inline ASH") (:generator 3 (cond ((and (= amount 1) (not (location= number result))) (inst lea result (make-ea :qword :base number :index number))) ((and (= amount 2) (not (location= number result))) (inst lea result (make-ea :qword :index number :scale 4))) ((and (= amount 3) (not (location= number result))) (inst lea result (make-ea :qword :index number :scale 8))) (t (move result number) (cond ((plusp amount) (inst shl result amount)) (t (inst sar result (min 63 (- amount)))))))))(define-vop (fast-ash-c/unsigned=>unsigned) (:translate ash) (:policy :fast-safe) (:args (number :scs (unsigned-reg) :target result :load-if (not (and (sc-is number unsigned-stack) (sc-is result unsigned-stack) (location= number result))))) (:info amount)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -