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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
          (t           (move result number)           (cond ((< -32 amount 32)                  ;; this code is used both in ASH and ASH-MOD32, so                  ;; be careful                  (if (plusp amount)                      (inst shl result amount)                      (inst shr result (- amount))))                 (t (if (sc-is result unsigned-reg)                        (inst xor result result)                        (inst mov result 0))))))))(define-vop (fast-ash-left/signed=>signed)  (:translate ash)  (:args (number :scs (signed-reg) :target result                 :load-if (not (and (sc-is number signed-stack)                                    (sc-is result signed-stack)                                    (location= number result))))         (amount :scs (unsigned-reg) :target ecx))  (:arg-types signed-num positive-fixnum)  (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx)  (:results (result :scs (signed-reg) :from (:argument 0)                    :load-if (not (and (sc-is number signed-stack)                                       (sc-is result signed-stack)                                       (location= number result)))))  (:result-types signed-num)  (:policy :fast-safe)  (:note "inline ASH")  (:generator 4    (move result number)    (move ecx amount)    (inst shl result :cl)))(define-vop (fast-ash-left/unsigned=>unsigned)  (:translate ash)  (:args (number :scs (unsigned-reg) :target result                 :load-if (not (and (sc-is number unsigned-stack)                                    (sc-is result unsigned-stack)                                    (location= number result))))         (amount :scs (unsigned-reg) :target ecx))  (:arg-types unsigned-num positive-fixnum)  (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx)  (:results (result :scs (unsigned-reg) :from (:argument 0)                    :load-if (not (and (sc-is number unsigned-stack)                                       (sc-is result unsigned-stack)                                       (location= number result)))))  (:result-types unsigned-num)  (:policy :fast-safe)  (:note "inline ASH")  (:generator 4    (move result number)    (move ecx amount)    (inst shl result :cl)))(define-vop (fast-ash/signed=>signed)  (:translate ash)  (:policy :fast-safe)  (:args (number :scs (signed-reg) :target result)         (amount :scs (signed-reg) :target ecx))  (:arg-types signed-num signed-num)  (:results (result :scs (signed-reg) :from (:argument 0)))  (:result-types signed-num)  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx)  (:note "inline ASH")  (:generator 5    (move result number)    (move ecx amount)    (inst or ecx ecx)    (inst jmp :ns positive)    (inst neg ecx)    (inst cmp ecx 31)    (inst jmp :be okay)    (inst mov ecx 31)    OKAY    (inst sar result :cl)    (inst jmp done)    POSITIVE    ;; The result-type ensures us that this shift will not overflow.    (inst shl result :cl)    DONE))(define-vop (fast-ash/unsigned=>unsigned)  (:translate ash)  (:policy :fast-safe)  (:args (number :scs (unsigned-reg) :target result)         (amount :scs (signed-reg) :target ecx))  (:arg-types unsigned-num signed-num)  (:results (result :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num)  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx)  (:note "inline ASH")  (:generator 5    (move result number)    (move ecx amount)    (inst or ecx ecx)    (inst jmp :ns positive)    (inst neg ecx)    (inst cmp ecx 31)    (inst jmp :be okay)    (inst xor result result)    (inst jmp done)    OKAY    (inst shr result :cl)    (inst jmp done)    POSITIVE    ;; The result-type ensures us that this shift will not overflow.    (inst shl result :cl)    DONE))(in-package "SB!C")(defknown %lea (integer integer (member 1 2 4 8) (signed-byte 32))  integer  (foldable flushable movable))(defoptimizer (%lea derive-type) ((base index scale disp))  (when (and (constant-lvar-p scale)             (constant-lvar-p disp))    (let ((scale (lvar-value scale))          (disp (lvar-value disp))          (base-type (lvar-type base))          (index-type (lvar-type index)))      (when (and (numeric-type-p base-type)                 (numeric-type-p index-type))        (let ((base-lo (numeric-type-low base-type))              (base-hi (numeric-type-high base-type))              (index-lo (numeric-type-low index-type))              (index-hi (numeric-type-high index-type)))          (make-numeric-type :class 'integer                             :complexp :real                             :low (when (and base-lo index-lo)                                    (+ base-lo (* index-lo scale) disp))                             :high (when (and base-hi index-hi)                                     (+ base-hi (* index-hi scale) disp))))))))(defun %lea (base index scale disp)  (+ base (* index scale) disp))(in-package "SB!VM")(define-vop (%lea/unsigned=>unsigned)  (:translate %lea)  (:policy :fast-safe)  (:args (base :scs (unsigned-reg))         (index :scs (unsigned-reg)))  (:info scale disp)  (:arg-types unsigned-num unsigned-num              (:constant (member 1 2 4 8))              (:constant (signed-byte 32)))  (:results (r :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 5    (inst lea r (make-ea :dword :base base :index index                         :scale scale :disp disp))))(define-vop (%lea/signed=>signed)  (:translate %lea)  (:policy :fast-safe)  (:args (base :scs (signed-reg))         (index :scs (signed-reg)))  (:info scale disp)  (:arg-types signed-num signed-num              (:constant (member 1 2 4 8))              (:constant (signed-byte 32)))  (:results (r :scs (signed-reg)))  (:result-types signed-num)  (:generator 4    (inst lea r (make-ea :dword :base base :index index                         :scale scale :disp disp))))(define-vop (%lea/fixnum=>fixnum)  (:translate %lea)  (:policy :fast-safe)  (:args (base :scs (any-reg))         (index :scs (any-reg)))  (:info scale disp)  (:arg-types tagged-num tagged-num              (:constant (member 1 2 4 8))              (:constant (signed-byte 32)))  (:results (r :scs (any-reg)))  (:result-types tagged-num)  (:generator 3    (inst lea r (make-ea :dword :base base :index index                         :scale scale :disp disp))));;; FIXME: before making knowledge of this too public, it needs to be;;; fixed so that it's actually _faster_ than the non-CMOV version; at;;; least on my Celeron-XXX laptop, this version is marginally slower;;; than the above version with branches.  -- CSR, 2003-09-04(define-vop (fast-cmov-ash/unsigned=>unsigned)  (:translate ash)  (:policy :fast-safe)  (:args (number :scs (unsigned-reg) :target result)         (amount :scs (signed-reg) :target ecx))  (:arg-types unsigned-num signed-num)  (:results (result :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num)  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx)  (:temporary (:sc any-reg :from (:eval 0) :to (:eval 1)) zero)  (:note "inline ASH")  (:guard (member :cmov *backend-subfeatures*))  (:generator 4    (move result number)    (move ecx amount)    (inst or ecx ecx)    (inst jmp :ns positive)    (inst neg ecx)    (inst xor zero zero)    (inst shr result :cl)    (inst cmp ecx 31)    (inst cmov :nbe result zero)    (inst jmp done)    POSITIVE    ;; The result-type ensures us that this shift will not overflow.    (inst shl result :cl)    DONE))(define-vop (signed-byte-32-len)  (:translate integer-length)  (:note "inline (signed-byte 32) integer-length")  (:policy :fast-safe)  (:args (arg :scs (signed-reg) :target res))  (:arg-types signed-num)  (:results (res :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 28    (move res arg)    (if (sc-is res unsigned-reg)        (inst test res res)        (inst cmp res 0))    (inst jmp :ge POS)    (inst not res)    POS    (inst bsr res res)    (inst jmp :z zero)    (inst inc res)    (inst jmp done)    ZERO    (inst xor res res)    DONE))(define-vop (unsigned-byte-32-len)  (:translate integer-length)  (:note "inline (unsigned-byte 32) integer-length")  (:policy :fast-safe)  (:args (arg :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (res :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 26    (inst bsr res arg)    (inst jmp :z zero)    (inst inc res)    (inst jmp done)    ZERO    (inst xor res res)    DONE))(define-vop (unsigned-byte-32-count)  (:translate logcount)  (:note "inline (unsigned-byte 32) logcount")  (:policy :fast-safe)  (:args (arg :scs (unsigned-reg) :target result))  (:arg-types unsigned-num)  (:results (result :scs (unsigned-reg)))  (:result-types positive-fixnum)  (:temporary (:sc unsigned-reg) temp)  (:generator 14    ;; See the comments below for how the algorithm works. The tricks    ;; used can be found for example in AMD's software optimization    ;; guide or at "http://www.hackersdelight.org/HDcode/pop.cc" in the    ;; function "pop1".    ;; Calculate 2-bit sums. Note that the value of a two-digit binary    ;; number is the sum of the right digit and twice the left digit.    ;; Thus we can calculate the sum of the two digits by shifting the    ;; left digit to the right position and doing a two-bit subtraction.    ;; This subtraction will never create a borrow and thus can be made    ;; on all 16 2-digit numbers at once.    (move result arg)    (move temp arg)    (inst shr result 1)    (inst and result #x55555555)    (inst sub temp result)    ;; Calculate 4-bit sums by straightforward shift, mask and add.    ;; Note that we shift the source operand of the MOV and not its    ;; destination so that the SHR and the MOV can execute in the same    ;; clock cycle.    (inst mov result temp)    (inst shr temp 2)    (inst and result #x33333333)    (inst and temp #x33333333)    (inst add result temp)    ;; Calculate 8-bit sums. Since each sum is at most 8, which fits    ;; into 4 bits, we can apply the mask after the addition, saving one    ;; instruction.    (inst mov temp result)    (inst shr result 4)    (inst add result temp)    (inst and result #x0f0f0f0f)    ;; Calculate the two 16-bit sums and the 32-bit sum. No masking is    ;; necessary inbetween since the final sum is at most 32 which fits    ;; into 6 bits.    (inst mov temp result)    (inst shr result 8)    (inst add result temp)    (inst mov temp result)    (inst shr result 16)    (inst add result temp)    (inst and result #xff)));;;; binary conditional VOPs(define-vop (fast-conditional)  (:conditional)  (:info target not-p)  (:effects)  (:affected)  (:policy :fast-safe))(define-vop (fast-conditional/fixnum fast-conditional)  (:args (x :scs (any-reg)            :load-if (not (and (sc-is x control-stack)                               (sc-is y any-reg))))         (y :scs (any-reg control-stack)))  (:arg-types tagged-num tagged-num)  (:note "inline fixnum comparison"))(define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg control-stack)))  (:arg-types tagged-num (:constant (signed-byte 30)))  (:info target not-p y))(define-vop (fast-conditional/signed fast-conditional)  (:args (x :scs (signed-reg)            :load-if (not (and (sc-is x signed-stack)                               (sc-is y signed-reg))))         (y :scs (signed-reg signed-stack)))  (:arg-types signed-num signed-num)  (:note "inline (signed-byte 32) comparison"))

⌨️ 快捷键说明

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