⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
           (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 + -