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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 2 页
字号:
;;;; the VM definition arithmetic VOPs for the Alpha;;;; 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 (fixnum-unop)  (:args (x :scs (any-reg)))  (:results (res :scs (any-reg)))  (:note "inline fixnum arithmetic")  (:arg-types tagged-num)  (:result-types tagged-num)  (:policy :fast-safe))(define-vop (signed-unop)  (:args (x :scs (signed-reg)))  (:results (res :scs (signed-reg)))  (:note "inline (signed-byte 64) arithmetic")  (:arg-types signed-num)  (:result-types signed-num)  (:policy :fast-safe))(define-vop (fast-negate/fixnum fixnum-unop)  (:translate %negate)  (:generator 1    (inst subq zero-tn x res)))(define-vop (fast-negate/signed signed-unop)  (:translate %negate)  (:generator 2    (inst subq zero-tn x res)))(define-vop (fast-lognot/fixnum fixnum-unop)  (:translate lognot)  (:generator 1    (inst eqv x fixnum-tag-mask res)))(define-vop (fast-lognot/signed signed-unop)  (:translate lognot)  (:generator 2    (inst not x res)));;;; binary fixnum operations;;; Assume that any constant operand is the second arg...(define-vop (fast-fixnum-binop)  (:args (x :target r :scs (any-reg))         (y :target r :scs (any-reg)))  (:arg-types tagged-num tagged-num)  (:results (r :scs (any-reg)))  (:result-types tagged-num)  (:note "inline fixnum arithmetic")  (:effects)  (:affected)  (:policy :fast-safe))(define-vop (fast-unsigned-binop)  (:args (x :target r :scs (unsigned-reg))         (y :target r :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num)  (:results (r :scs (unsigned-reg)))  (:result-types unsigned-num)  (:note "inline (unsigned-byte 64) arithmetic")  (:effects)  (:affected)  (:policy :fast-safe))(define-vop (fast-signed-binop)  (:args (x :target r :scs (signed-reg))         (y :target r :scs (signed-reg)))  (:arg-types signed-num signed-num)  (:results (r :scs (signed-reg)))  (:result-types signed-num)  (:note "inline (signed-byte 64) arithmetic")  (:effects)  (:affected)  (:policy :fast-safe))(define-vop (fast-fixnum-c-binop fast-fixnum-binop)  (:args (x :target r :scs (any-reg)))  (:info y)  (:arg-types tagged-num (:constant integer)))(define-vop (fast-signed-c-binop fast-signed-binop)  (:args (x :target r :scs (signed-reg)))  (:info y)  (:arg-types signed-num (:constant integer)))(define-vop (fast-unsigned-c-binop fast-unsigned-binop)  (:args (x :target r :scs (unsigned-reg)))  (:info y)  (:arg-types unsigned-num (:constant integer)))(defmacro define-binop (translate cost untagged-cost op                        tagged-type untagged-type                        &optional arg-swap restore-fixnum-mask)  `(progn     (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")                  fast-fixnum-binop)       ,@(when restore-fixnum-mask           `((:temporary (:sc non-descriptor-reg) temp)))       (:args (x ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg))              (y ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg)))       (:translate ,translate)       (:generator ,(1+ cost)         ,(if arg-swap              `(inst ,op y x ,(if restore-fixnum-mask 'temp 'r))              `(inst ,op x y ,(if restore-fixnum-mask 'temp 'r)))         ,@(when restore-fixnum-mask             `((inst bic temp #.(ash lowtag-mask -1) r)))))     (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")                  fast-signed-binop)       (:args (x :target r :scs (signed-reg))              (y :target r :scs (signed-reg)))       (:translate ,translate)       (:generator ,(1+ untagged-cost)         ,(if arg-swap              `(inst ,op y x r)              `(inst ,op x y r))))     (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED")                  fast-unsigned-binop)       (:args (x :target r :scs (unsigned-reg))              (y :target r :scs (unsigned-reg)))       (:translate ,translate)       (:generator ,(1+ untagged-cost)         ,(if arg-swap              `(inst ,op y x r)              `(inst ,op x y r))))     ,@(when (and tagged-type (not arg-swap))         `((define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")                        fast-fixnum-c-binop)             (:args (x ,@(unless restore-fixnum-mask `(:target r))                       :scs (any-reg)))             (:arg-types tagged-num (:constant ,tagged-type))             ,@(when restore-fixnum-mask                 `((:temporary (:sc non-descriptor-reg) temp)))             (:translate ,translate)             (:generator ,cost                (inst ,op x (fixnumize y) ,(if restore-fixnum-mask 'temp 'r))                ,@(when restore-fixnum-mask                    `((inst bic temp #.(ash lowtag-mask -1) r)))))))     ,@(when (and untagged-type (not arg-swap))         `((define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")                        fast-signed-c-binop)             (:arg-types signed-num (:constant ,untagged-type))             (:translate ,translate)             (:generator ,untagged-cost                (inst ,op x y r)))           (define-vop (,(symbolicate "FAST-" translate                                      "-C/UNSIGNED=>UNSIGNED")                        fast-unsigned-c-binop)             (:arg-types unsigned-num (:constant ,untagged-type))             (:translate ,translate)             (:generator ,untagged-cost                (inst ,op x y r)))))))(define-binop + 1 5 addq (unsigned-byte 6) (unsigned-byte 8))(define-binop - 1 5 subq (unsigned-byte 6) (unsigned-byte 8))(define-binop logand 1 3 and (unsigned-byte 6) (unsigned-byte 8))(define-binop logandc1 1 3 bic (unsigned-byte 6) (unsigned-byte 8) t)(define-binop logandc2 1 3 bic (unsigned-byte 6) (unsigned-byte 8))(define-binop logior 1 3 bis (unsigned-byte 6) (unsigned-byte 8))(define-binop logorc1 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) t t)(define-binop logorc2 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) nil t)(define-binop logxor 1 3 xor (unsigned-byte 6) (unsigned-byte 8))(define-binop logeqv 1 3 eqv (unsigned-byte 6) (unsigned-byte 8) nil t);;; special cases for LOGAND where we can use a mask operation(define-vop (fast-logand-c-mask/unsigned=>unsigned fast-unsigned-c-binop)  (:translate logand)  (:arg-types unsigned-num              (:constant (or (integer #xffffffff #xffffffff)                             (integer #xffffffff00000000 #xffffffff00000000))))  (:generator 1    (ecase y      (#xffffffff (inst mskll x 4 r))      (#xffffffff00000000 (inst mskll x 0 r)))));;;; shifting(define-vop (fast-ash/unsigned=>unsigned)  (:note "inline ASH")  (:args (number :scs (unsigned-reg) :to :save)         (amount :scs (signed-reg)))  (:arg-types unsigned-num signed-num)  (:results (result :scs (unsigned-reg)))  (:result-types unsigned-num)  (:translate ash)  (:policy :fast-safe)  (:temporary (:sc non-descriptor-reg) ndesc)  (:temporary (:sc non-descriptor-reg) temp)  (:generator 3    (inst bge amount positive)    (inst subq zero-tn amount ndesc)    (inst cmplt ndesc 64 temp)    (inst srl number ndesc result)    ;; FIXME: this looks like a candidate for a conditional move --    ;; CSR, 2003-09-10    (inst bne temp done)    (move zero-tn result)    (inst br zero-tn done)    POSITIVE    (inst sll number amount result)    DONE))(define-vop (fast-ash/signed=>signed)  (:note "inline ASH")  (:args (number :scs (signed-reg) :to :save)         (amount :scs (signed-reg)))  (:arg-types signed-num signed-num)  (:results (result :scs (signed-reg)))  (:result-types signed-num)  (:translate ash)  (:policy :fast-safe)  (:temporary (:sc non-descriptor-reg) ndesc)  (:temporary (:sc non-descriptor-reg) temp)  (:generator 3    (inst bge amount positive)    (inst subq zero-tn amount ndesc)    (inst cmplt ndesc 63 temp)    (inst sra number ndesc result)    (inst bne temp done)    (inst sra number 63 result)    (inst br zero-tn done)    POSITIVE    (inst sll number amount result)    DONE))(define-vop (fast-ash-c/signed=>signed)  (:policy :fast-safe)  (:translate ash)  (:note nil)  (:args (number :scs (signed-reg)))  (:info count)  (:arg-types signed-num (:constant integer))  (:results (result :scs (signed-reg)))  (:result-types signed-num)  (:generator 1    (cond      ((< count 0) (inst sra number (min 63 (- count)) result))      ((> count 0) (inst sll number (min 63 count) result))      (t (bug "identity ASH not transformed away")))))(define-vop (fast-ash-c/unsigned=>unsigned)  (:policy :fast-safe)  (:translate ash)  (:note nil)  (:args (number :scs (unsigned-reg)))  (:info count)  (:arg-types unsigned-num (:constant integer))  (:results (result :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 1    (cond      ((< count -63) (move zero-tn result))      ((< count 0) (inst sra number (- count) result))      ((> count 0) (inst sll number (min 63 count) result))      (t (bug "identity ASH not transformed away")))))(macrolet ((def (name sc-type type result-type cost)             `(define-vop (,name)                (:note "inline ASH")                (:translate ash)                (:args (number :scs (,sc-type))                       (amount :scs (signed-reg unsigned-reg immediate)))                (:arg-types ,type positive-fixnum)                (:results (result :scs (,result-type)))                (:result-types ,type)                (:policy :fast-safe)                (:generator ,cost                   (sc-case amount                     ((signed-reg unsigned-reg)                      (inst sll number amount result))                     (immediate                      (let ((amount (tn-value amount)))                        (aver (> amount 0))                        (inst sll number amount result))))))))  (def fast-ash-left/fixnum=>fixnum any-reg tagged-num any-reg 2)  (def fast-ash-left/signed=>signed signed-reg signed-num signed-reg 3)  (def fast-ash-left/unsigned=>unsigned unsigned-reg unsigned-num unsigned-reg 3))(define-vop (signed-byte-64-len)  (:translate integer-length)  (:note "inline (signed-byte 64) integer-length")  (:policy :fast-safe)  (:args (arg :scs (signed-reg) :to (:argument 1)))  (:arg-types signed-num)  (:results (res :scs (any-reg)))  (:result-types positive-fixnum)  (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift)  (:generator 30    (inst not arg shift)    (inst cmovge arg arg shift)    (inst subq zero-tn (fixnumize 1) res)    (inst sll shift 1 shift)    LOOP    (inst addq res (fixnumize 1) res)    (inst srl shift 1 shift)    (inst bne shift loop)))(define-vop (unsigned-byte-64-count)  (:translate logcount)  (:note "inline (unsigned-byte 64) logcount")  (:policy :fast-safe)  (:args (arg :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (res :scs (unsigned-reg)))  (:result-types positive-fixnum)  (:guard (member :cix *backend-subfeatures*))  (:generator 1    (inst ctpop zero-tn arg res)))(define-vop (unsigned-byte-64-count)  (:translate logcount)  (:note "inline (unsigned-byte 64) logcount")  (:policy :fast-safe)  (:args (arg :scs (unsigned-reg) :target num))  (:arg-types unsigned-num)  (:results (res :scs (unsigned-reg)))  (:result-types positive-fixnum)  (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)                    :target res) num)  (:temporary (:scs (non-descriptor-reg)) mask temp)  (:generator 60    ;; FIXME: now this looks expensive, what with these 64bit loads.    ;; Maybe a loop and count would be faster?  -- CSR, 2003-09-10    (inst li #x5555555555555555 mask)    (inst srl arg 1 temp)    (inst and arg mask num)    (inst and temp mask temp)    (inst addq num temp num)    (inst li #x3333333333333333 mask)    (inst srl num 2 temp)    (inst and num mask num)    (inst and temp mask temp)    (inst addq num temp num)    (inst li #x0f0f0f0f0f0f0f0f mask)    (inst srl num 4 temp)    (inst and num mask num)    (inst and temp mask temp)    (inst addq num temp num)    (inst li #x00ff00ff00ff00ff mask)    (inst srl num 8 temp)    (inst and num mask num)    (inst and temp mask temp)    (inst addq num temp num)    (inst li #x0000ffff0000ffff mask)    (inst srl num 16 temp)    (inst and num mask num)    (inst and temp mask temp)    (inst addq num temp num)    (inst li #x00000000ffffffff mask)    (inst srl num 32 temp)    (inst and num mask num)    (inst and temp mask temp)    (inst addq num temp res)));;;; multiplying(define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)  (:temporary (:scs (non-descriptor-reg)) temp)  (:translate *)  (:generator 4    (inst sra y n-fixnum-tag-bits temp)    (inst mulq x temp r)))(define-vop (fast-*/signed=>signed fast-signed-binop)  (:translate *)  (:generator 3    (inst mulq x y r)))(define-vop (fast-*/unsigned=>unsigned fast-unsigned-binop)  (:translate *)  (:generator 3    (inst mulq x y r)));;;; Modular functions:(define-modular-fun lognot-mod64 (x) lognot :untagged nil 64)(define-vop (lognot-mod64/unsigned=>unsigned)  (:translate lognot-mod64)  (:args (x :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (res :scs (unsigned-reg)))  (:result-types unsigned-num)  (:policy :fast-safe)  (:generator 1    (inst not x res)))(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))(macrolet    ((define-modular-backend (fun &optional constantp)       (let ((mfun-name (symbolicate fun '-mod64))             (modvop (symbolicate 'fast- fun '-mod64/unsigned=>unsigned))             (modcvop (symbolicate 'fast- fun '-mod64-c/unsigned=>unsigned))             (vop (symbolicate 'fast- fun '/unsigned=>unsigned))             (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned)))         `(progn            (define-modular-fun ,mfun-name (x y) ,fun :untagged nil 64)            (define-vop (,modvop ,vop)              (:translate ,mfun-name))            ,@(when constantp                `((define-vop (,modcvop ,cvop)                    (:translate ,mfun-name))))))))  (define-modular-backend + t)  (define-modular-backend - t)  (define-modular-backend logeqv t)  (define-modular-backend logandc1)  (define-modular-backend logandc2 t)  (define-modular-backend logorc1)  (define-modular-backend logorc2 t))(define-source-transform lognand (x y)  `(lognot (logand ,x ,y)))(define-source-transform lognor (x y)  `(lognot (logior ,x ,y)))

⌨️ 快捷键说明

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