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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
;;;; the VM definition of arithmetic VOPs for the x86-64;;;; This software is part of the SBCL system. See the README file for;;;; more information.;;;;;;;; This software is derived from the CMU CL system, which was;;;; written at Carnegie Mellon University and released into the;;;; public domain. The software is in the public domain and is;;;; provided with absolutely no warranty. See the COPYING and CREDITS;;;; files for more information.(in-package "SB!VM");;;; unary operations(define-vop (fast-safe-arith-op)  (:policy :fast-safe)  (:effects)  (:affected))(define-vop (fixnum-unop fast-safe-arith-op)  (:args (x :scs (any-reg) :target res))  (:results (res :scs (any-reg)))  (:note "inline fixnum arithmetic")  (:arg-types tagged-num)  (:result-types tagged-num))(define-vop (signed-unop fast-safe-arith-op)  (:args (x :scs (signed-reg) :target res))  (:results (res :scs (signed-reg)))  (:note "inline (signed-byte 64) arithmetic")  (:arg-types signed-num)  (:result-types signed-num))(define-vop (fast-negate/fixnum fixnum-unop)  (:translate %negate)  (:generator 1    (move res x)    (inst neg res)))(define-vop (fast-negate/signed signed-unop)  (:translate %negate)  (:generator 2    (move res x)    (inst neg res)))(define-vop (fast-lognot/fixnum fixnum-unop)  (:translate lognot)  (:generator 1    (move res x)    (inst xor res (fixnumize -1))))(define-vop (fast-lognot/signed signed-unop)  (:translate lognot)  (:generator 2    (move res x)    (inst not res)));;;; binary fixnum operations;;; Assume that any constant operand is the second arg...(define-vop (fast-fixnum-binop fast-safe-arith-op)  (:args (x :target r :scs (any-reg)            :load-if (not (and (sc-is x control-stack)                               (sc-is y any-reg)                               (sc-is r control-stack)                               (location= x r))))         (y :scs (any-reg control-stack)))  (:arg-types tagged-num tagged-num)  (:results (r :scs (any-reg) :from (:argument 0)               :load-if (not (and (sc-is x control-stack)                                  (sc-is y any-reg)                                  (sc-is r control-stack)                                  (location= x r)))))  (:result-types tagged-num)  (:note "inline fixnum arithmetic"))(define-vop (fast-unsigned-binop fast-safe-arith-op)  (:args (x :target r :scs (unsigned-reg)            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is y unsigned-reg)                               (sc-is r unsigned-stack)                               (location= x r))))         (y :scs (unsigned-reg unsigned-stack)))  (:arg-types unsigned-num unsigned-num)  (:results (r :scs (unsigned-reg) :from (:argument 0)            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is y unsigned-reg)                               (sc-is r unsigned-stack)                               (location= x r)))))  (:result-types unsigned-num)  (:note "inline (unsigned-byte 64) arithmetic"))(define-vop (fast-signed-binop fast-safe-arith-op)  (:args (x :target r :scs (signed-reg)            :load-if (not (and (sc-is x signed-stack)                               (sc-is y signed-reg)                               (sc-is r signed-stack)                               (location= x r))))         (y :scs (signed-reg signed-stack)))  (:arg-types signed-num signed-num)  (:results (r :scs (signed-reg) :from (:argument 0)            :load-if (not (and (sc-is x signed-stack)                               (sc-is y signed-reg)                               (sc-is r signed-stack)                               (location= x r)))))  (:result-types signed-num)  (:note "inline (signed-byte 64) arithmetic"))(define-vop (fast-fixnum-binop-c fast-safe-arith-op)  (:args (x :target r :scs (any-reg control-stack)))  (:info y)  (:arg-types tagged-num (:constant (signed-byte 29)))  (:results (r :scs (any-reg)               :load-if (not (location= x r))))  (:result-types tagged-num)  (:note "inline fixnum arithmetic"));; 31 not 64 because it's hard work loading 64 bit constants, and since;; sign-extension of immediates causes problems with 32.(define-vop (fast-unsigned-binop-c fast-safe-arith-op)  (:args (x :target r :scs (unsigned-reg unsigned-stack)))  (:info y)  (:arg-types unsigned-num (:constant (unsigned-byte 31)))  (:results (r :scs (unsigned-reg)               :load-if (not (location= x r))))  (:result-types unsigned-num)  (:note "inline (unsigned-byte 64) arithmetic"))(define-vop (fast-signed-binop-c fast-safe-arith-op)  (:args (x :target r :scs (signed-reg signed-stack)))  (:info y)  (:arg-types signed-num (:constant (signed-byte 32)))  (:results (r :scs (signed-reg)               :load-if (not (location= x r))))  (:result-types signed-num)  (:note "inline (signed-byte 64) arithmetic"))(macrolet ((define-binop (translate untagged-penalty op)             `(progn                (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")                             fast-fixnum-binop)                  (:translate ,translate)                  (:generator 2                              (move r x)                              (inst ,op r y)))                (define-vop (,(symbolicate 'fast- translate '-c/fixnum=>fixnum)                             fast-fixnum-binop-c)                  (:translate ,translate)                  (:generator 1                  (move r x)                  (inst ,op r (fixnumize y))))                (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")                             fast-signed-binop)                  (:translate ,translate)                  (:generator ,(1+ untagged-penalty)                  (move r x)                  (inst ,op r y)))                (define-vop (,(symbolicate 'fast- translate '-c/signed=>signed)                             fast-signed-binop-c)                  (:translate ,translate)                  (:generator ,untagged-penalty                  (move r x)                  (inst ,op r y)))                (define-vop (,(symbolicate "FAST-"                                           translate                                           "/UNSIGNED=>UNSIGNED")                fast-unsigned-binop)                  (:translate ,translate)                  (:generator ,(1+ untagged-penalty)                  (move r x)                  (inst ,op r y)))                (define-vop (,(symbolicate 'fast-                                           translate                                           '-c/unsigned=>unsigned)                             fast-unsigned-binop-c)                  (:translate ,translate)                  (:generator ,untagged-penalty                  (move r x)                  (inst ,op r y))))))  ;;(define-binop + 4 add)  (define-binop - 4 sub)  (define-binop logand 2 and)  (define-binop logior 2 or)  (define-binop logxor 2 xor));;; Special handling of add on the x86; can use lea to avoid a;;; register load, otherwise it uses add.(define-vop (fast-+/fixnum=>fixnum fast-safe-arith-op)  (:translate +)  (:args (x :scs (any-reg) :target r            :load-if (not (and (sc-is x control-stack)                               (sc-is y any-reg)                               (sc-is r control-stack)                               (location= x r))))         (y :scs (any-reg control-stack)))  (:arg-types tagged-num tagged-num)  (:results (r :scs (any-reg) :from (:argument 0)               :load-if (not (and (sc-is x control-stack)                                  (sc-is y any-reg)                                  (sc-is r control-stack)                                  (location= x r)))))  (:result-types tagged-num)  (:note "inline fixnum arithmetic")  (:generator 2    (cond ((and (sc-is x any-reg) (sc-is y any-reg) (sc-is r any-reg)                (not (location= x r)))           (inst lea r (make-ea :qword :base x :index y :scale 1)))          (t           (move r x)           (inst add r y)))))(define-vop (fast-+-c/fixnum=>fixnum fast-safe-arith-op)  (:translate +)  (:args (x :target r :scs (any-reg control-stack)))  (:info y)  (:arg-types tagged-num (:constant (signed-byte 29)))  (:results (r :scs (any-reg)               :load-if (not (location= x r))))  (:result-types tagged-num)  (:note "inline fixnum arithmetic")  (:generator 1    (cond ((and (sc-is x any-reg) (sc-is r any-reg) (not (location= x r)))           (inst lea r (make-ea :qword :base x :disp (fixnumize y))))          (t           (move r x)           (inst add r (fixnumize y))))))(define-vop (fast-+/signed=>signed fast-safe-arith-op)  (:translate +)  (:args (x :scs (signed-reg) :target r            :load-if (not (and (sc-is x signed-stack)                               (sc-is y signed-reg)                               (sc-is r signed-stack)                               (location= x r))))         (y :scs (signed-reg signed-stack)))  (:arg-types signed-num signed-num)  (:results (r :scs (signed-reg) :from (:argument 0)               :load-if (not (and (sc-is x signed-stack)                                  (sc-is y signed-reg)                                  (location= x r)))))  (:result-types signed-num)  (:note "inline (signed-byte 64) arithmetic")  (:generator 5    (cond ((and (sc-is x signed-reg) (sc-is y signed-reg) (sc-is r signed-reg)                (not (location= x r)))           (inst lea r (make-ea :qword :base x :index y :scale 1)))          (t           (move r x)           (inst add r y)))));;;; Special logand cases: (logand signed unsigned) => unsigned(define-vop (fast-logand/signed-unsigned=>unsigned             fast-logand/unsigned=>unsigned)  (:args (x :target r :scs (signed-reg)            :load-if (not (and (sc-is x signed-stack)                               (sc-is y unsigned-reg)                               (sc-is r unsigned-stack)                               (location= x r))))         (y :scs (unsigned-reg unsigned-stack)))  (:arg-types signed-num unsigned-num))(define-vop (fast-logand-c/signed-unsigned=>unsigned             fast-logand-c/unsigned=>unsigned)  (:args (x :target r :scs (signed-reg signed-stack)))  (:arg-types signed-num (:constant (unsigned-byte 31))))(define-vop (fast-logand/unsigned-signed=>unsigned             fast-logand/unsigned=>unsigned)  (:args (x :target r :scs (unsigned-reg)            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is y signed-reg)                               (sc-is r unsigned-stack)                               (location= x r))))         (y :scs (signed-reg signed-stack)))  (:arg-types unsigned-num signed-num))(define-vop (fast-+-c/signed=>signed fast-safe-arith-op)  (:translate +)  (:args (x :target r :scs (signed-reg signed-stack)))  (:info y)  (:arg-types signed-num (:constant (signed-byte 32)))  (:results (r :scs (signed-reg)               :load-if (not (location= x r))))  (:result-types signed-num)  (:note "inline (signed-byte 64) arithmetic")  (:generator 4    (cond ((and (sc-is x signed-reg) (sc-is r signed-reg)                (not (location= x r)))           (inst lea r (make-ea :qword :base x :disp y)))          (t           (move r x)           (if (= y 1)               (inst inc r)             (inst add r y))))))(define-vop (fast-+/unsigned=>unsigned fast-safe-arith-op)  (:translate +)  (:args (x :scs (unsigned-reg) :target r            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is y unsigned-reg)                               (sc-is r unsigned-stack)                               (location= x r))))         (y :scs (unsigned-reg unsigned-stack)))  (:arg-types unsigned-num unsigned-num)  (:results (r :scs (unsigned-reg) :from (:argument 0)               :load-if (not (and (sc-is x unsigned-stack)                                  (sc-is y unsigned-reg)                                  (sc-is r unsigned-stack)                                  (location= x r)))))  (:result-types unsigned-num)  (:note "inline (unsigned-byte 64) arithmetic")  (:generator 5    (cond ((and (sc-is x unsigned-reg) (sc-is y unsigned-reg)                (sc-is r unsigned-reg) (not (location= x r)))           (inst lea r (make-ea :qword :base x :index y :scale 1)))          (t           (move r x)           (inst add r y)))))(define-vop (fast-+-c/unsigned=>unsigned fast-safe-arith-op)  (:translate +)  (:args (x :target r :scs (unsigned-reg unsigned-stack)))  (:info y)  (:arg-types unsigned-num (:constant (unsigned-byte 31)))  (:results (r :scs (unsigned-reg)               :load-if (not (location= x r))))  (:result-types unsigned-num)  (:note "inline (unsigned-byte 64) arithmetic")  (:generator 4    (cond ((and (sc-is x unsigned-reg) (sc-is r unsigned-reg)                (not (location= x r)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -