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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
  (:info target not-p)  (:effects)  (:affected)  (:policy :fast-safe));;; constant variants are declared for 32 bits not 64 bits, because;;; loading a 64 bit constant is silly(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 29)))  (: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 64) comparison"))(define-vop (fast-conditional-c/signed fast-conditional/signed)  (:args (x :scs (signed-reg signed-stack)))  (:arg-types signed-num (:constant (signed-byte 31)))  (:info target not-p y))(define-vop (fast-conditional/unsigned fast-conditional)  (:args (x :scs (unsigned-reg)            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is y unsigned-reg))))         (y :scs (unsigned-reg unsigned-stack)))  (:arg-types unsigned-num unsigned-num)  (:note "inline (unsigned-byte 64) comparison"))(define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)  (:args (x :scs (unsigned-reg unsigned-stack)))  (:arg-types unsigned-num (:constant (unsigned-byte 31)))  (:info target not-p y))(macrolet ((define-conditional-vop (tran cond unsigned not-cond not-unsigned)             `(progn                ,@(mapcar                   (lambda (suffix cost signed)                     `(define-vop (;; FIXME: These could be done more                                   ;; cleanly with SYMBOLICATE.                                   ,(intern (format nil "~:@(FAST-IF-~A~A~)"                                                    tran suffix))                                   ,(intern                                     (format nil "~:@(FAST-CONDITIONAL~A~)"                                             suffix)))                        (:translate ,tran)                        (:generator ,cost                                    (inst cmp x                                          ,(if (eq suffix '-c/fixnum)                                               '(fixnumize y)                                               'y))                                    (inst jmp (if not-p                                                  ,(if signed                                                       not-cond                                                       not-unsigned)                                                  ,(if signed                                                       cond                                                       unsigned))                                          target))))                   '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned);                  '(/fixnum  /signed  /unsigned)                   '(4 3 6 5 6 5)                   '(t t t t nil nil)))))  (define-conditional-vop < :l :b :ge :ae)  (define-conditional-vop > :g :a :le :be))(define-vop (fast-if-eql/signed fast-conditional/signed)  (:translate eql)  (:generator 6    (inst cmp x y)    (inst jmp (if not-p :ne :e) target)))(define-vop (fast-if-eql-c/signed fast-conditional-c/signed)  (:translate eql)  (:generator 5    (cond ((and (sc-is x signed-reg) (zerop y))           (inst test x x))  ; smaller instruction          (t           (inst cmp x y)))    (inst jmp (if not-p :ne :e) target)))(define-vop (fast-if-eql/unsigned fast-conditional/unsigned)  (:translate eql)  (:generator 6    (inst cmp x y)    (inst jmp (if not-p :ne :e) target)))(define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned)  (:translate eql)  (:generator 5    (cond ((and (sc-is x unsigned-reg) (zerop y))           (inst test x x))  ; smaller instruction          (t           (inst cmp x y)))    (inst jmp (if not-p :ne :e) target)));;; EQL/FIXNUM is funny because the first arg can be of any type, not just a;;; known fixnum.;;; These versions specify a fixnum restriction on their first arg. We have;;; also generic-eql/fixnum VOPs which are the same, but have no restriction on;;; the first arg and a higher cost. The reason for doing this is to prevent;;; fixnum specific operations from being used on word integers, spuriously;;; consing the argument.(define-vop (fast-eql/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")  (:translate eql)  (:generator 4    (inst cmp x y)    (inst jmp (if not-p :ne :e) target)))(define-vop (generic-eql/fixnum fast-eql/fixnum)  (:args (x :scs (any-reg descriptor-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)  (:variant-cost 7))(define-vop (fast-eql-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg control-stack)))  (:arg-types tagged-num (:constant (signed-byte 29)))  (:info target not-p y)  (:translate eql)  (:generator 2    (cond ((and (sc-is x any-reg) (zerop y))           (inst test x x))  ; smaller instruction          (t           (inst cmp x (fixnumize y))))    (inst jmp (if not-p :ne :e) target)))(define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)  (:args (x :scs (any-reg descriptor-reg control-stack)))  (:arg-types * (:constant (signed-byte 29)))  (:variant-cost 6));;;; 32-bit logical operations(define-vop (merge-bits)  (:translate merge-bits)  (:args (shift :scs (signed-reg unsigned-reg) :target ecx)         (prev :scs (unsigned-reg) :target result)         (next :scs (unsigned-reg)))  (:arg-types tagged-num unsigned-num unsigned-num)  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 0)) ecx)  (:results (result :scs (unsigned-reg) :from (:argument 1)))  (:result-types unsigned-num)  (:policy :fast-safe)  (:generator 4    (move ecx shift)    (move result prev)    (inst shrd result next :cl)));;; Only the lower 6 bits of the shift amount are significant.(define-vop (shift-towards-someplace)  (:policy :fast-safe)  (:args (num :scs (unsigned-reg) :target r)         (amount :scs (signed-reg) :target ecx))  (:arg-types unsigned-num tagged-num)  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx)  (:results (r :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num))(define-vop (shift-towards-start shift-towards-someplace)  (:translate shift-towards-start)  (:note "SHIFT-TOWARDS-START")  (:generator 1    (move r num)    (move ecx amount)    (inst shr r :cl)))(define-vop (shift-towards-end shift-towards-someplace)  (:translate shift-towards-end)  (:note "SHIFT-TOWARDS-END")  (:generator 1    (move r num)    (move ecx amount)    (inst shl r :cl)));;;; Modular functions(defmacro define-mod-binop ((name prototype) function)  `(define-vop (,name ,prototype)       (:args (x :target r :scs (unsigned-reg signed-reg)                 :load-if (not (and (or (sc-is x unsigned-stack)                                        (sc-is x signed-stack))                                    (or (sc-is y unsigned-reg)                                        (sc-is y signed-reg))                                    (or (sc-is r unsigned-stack)                                        (sc-is r signed-stack))                                    (location= x r))))              (y :scs (unsigned-reg signed-reg unsigned-stack signed-stack)))     (:arg-types untagged-num untagged-num)     (:results (r :scs (unsigned-reg signed-reg) :from (:argument 0)                  :load-if (not (and (or (sc-is x unsigned-stack)                                         (sc-is x signed-stack))                                     (or (sc-is y unsigned-reg)                                         (sc-is y unsigned-reg))                                     (or (sc-is r unsigned-stack)                                         (sc-is r unsigned-stack))                                     (location= x r)))))     (:result-types unsigned-num)     (:translate ,function)))(defmacro define-mod-binop-c ((name prototype) function)  `(define-vop (,name ,prototype)       (:args (x :target r :scs (unsigned-reg signed-reg)                 :load-if (not (and (or (sc-is x unsigned-stack)                                        (sc-is x signed-stack))                                    (or (sc-is r unsigned-stack)                                        (sc-is r signed-stack))                                    (location= x r)))))     (:info y)     (:arg-types untagged-num (:constant (or (unsigned-byte 31) (signed-byte 32))))     (:results (r :scs (unsigned-reg signed-reg) :from (:argument 0)                  :load-if (not (and (or (sc-is x unsigned-stack)                                         (sc-is x signed-stack))                                     (or (sc-is r unsigned-stack)                                         (sc-is r unsigned-stack))                                     (location= x r)))))     (:result-types unsigned-num)     (:translate ,function)))(macrolet ((def (name -c-p)             (let ((fun64 (intern (format nil "~S-MOD64" name)))                   (vopu (intern (format nil "FAST-~S/UNSIGNED=>UNSIGNED" name)))                   (vopcu (intern (format nil "FAST-~S-C/UNSIGNED=>UNSIGNED" name)))                   (vopf (intern (format nil "FAST-~S/FIXNUM=>FIXNUM" name)))                   (vopcf (intern (format nil "FAST-~S-C/FIXNUM=>FIXNUM" name)))                   (vop64u (intern (format nil "FAST-~S-MOD64/WORD=>UNSIGNED" name)))                   (vop64f (intern (format nil "FAST-~S-MOD64/FIXNUM=>FIXNUM" name)))                   (vop64cu (intern (format nil "FAST-~S-MOD64-C/WORD=>UNSIGNED" name)))                   (vop64cf (intern (format nil "FAST-~S-MOD64-C/FIXNUM=>FIXNUM" name)))                   (sfun61 (intern (format nil "~S-SMOD61" name)))                   (svop61f (intern (format nil "FAST-~S-SMOD61/FIXNUM=>FIXNUM" name)))                   (svop61cf (intern (format nil "FAST-~S-SMOD61-C/FIXNUM=>FIXNUM" name))))               `(progn                  (define-modular-fun ,fun64 (x y) ,name :untagged nil 64)                  (define-modular-fun ,sfun61 (x y) ,name :tagged t 61)                  (define-mod-binop (,vop64u ,vopu) ,fun64)                  (define-vop (,vop64f ,vopf) (:translate ,fun64))                  (define-vop (,svop61f ,vopf) (:translate ,sfun61))                  ,@(when -c-p                      `((define-mod-binop-c (,vop64cu ,vopcu) ,fun64)                        (define-vop (,svop61cf ,vopcf) (:translate ,sfun61))))))))  (def + t)  (def - t)  ;; (no -C variant as x86 MUL instruction doesn't take an immediate)  (def * nil))(define-vop (fast-ash-left-mod64-c/unsigned=>unsigned             fast-ash-c/unsigned=>unsigned)  (:translate ash-left-mod64))(define-vop (fast-ash-left-mod64/unsigned=>unsigned             fast-ash-left/unsigned=>unsigned))(deftransform ash-left-mod64 ((integer count)                              ((unsigned-byte 64) (unsigned-byte 6)))  (when (sb!c::constant-lvar-p count)    (sb!c::give-up-ir1-transform))  '(%primitive fast-ash-left-mod64/unsigned=>unsigned integer count))(define-vop (fast-ash-left-smod61-c/fixnum=>fixnum             fast-ash-c/fixnum=>fixnum)  (:translate ash-left-smod61))(define-vop (fast-ash-left-smod61/fixnum=>fixnum             fast-ash-left/fixnum=>fixnum))(deftransform ash-left-smod61 ((integer count)                               ((signed-byte 61) (unsigned-byte 6)))  (when (sb!c::constant-lvar-p count)    (sb!c::give-up-ir1-transform))  '(%primitive fast-ash-left-smod61/fixnum=>fixnum integer count))(in-package "SB!C")(defknown sb!vm::%lea-mod64 (integer integer (member 1 2 4 8) (signed-byte 64))  (unsigned-byte 64)  (foldable flushable movable))(defknown sb!vm::%lea-smod61 (integer integer (member 1 2 4 8) (signed-byte 64))  (signed-byte 61)  (foldable flushable movable))(define-modular-fun-optimizer %lea ((base index scale disp) :untagged nil :width width)  (when (and (<= width 64)             (constant-lvar-p scale)             (constant-lvar-p disp))    (cut-to-width base :untagged width nil)    (cut-to-width index :untagged width nil)    'sb!vm::%lea-mod64))(define-modular-fun-optimizer %lea ((base index scale disp) :tagged t :width width)  (when (and (<= width 61)             (constant-lvar-p scale)             (constant-lvar-p disp))    (cut-to-width base :tagged width t)    (cut-to-width index :tagged width t)    'sb!vm::%lea-smod61))#+sb-xc-host(progn  (defun sb!vm::%lea-mod64 (base index scale disp)    (ldb (byte 64 0) (%lea base index scale disp)))  (defun sb!vm::%lea-smod61 (base index scale disp)    (mask-signed-field 61 (%lea base index scale disp))))#-sb-xc-host(progn  (defun sb!vm::%lea-mod64 (base index scale disp)    (let ((base (logand base #xffffffffffffffff))          (index (logand index #xffffffffffffffff)))      ;; can't use modular version of %LEA, as we only have VOPs for      ;; constant SCALE and DISP.      (ldb (byte 64 0) (+ base (* index scale) disp))))  (defun sb!vm::%lea-smod61 (base index scale disp)    (let ((base (mask-signed-field 61 base))          (index (mask-signed-field 61 index)))      ;; can't use modular version of %LEA, as we only have VOPs for      ;; constant SCALE and DISP.      (mask-signed-field 61 (+ base (* index scale) disp)))))(in-package "SB!VM")

⌨️ 快捷键说明

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