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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 2 页
字号:
;;;; binary conditional VOPs(define-vop (fast-conditional)  (:conditional)  (:info target not-p)  (:effects)  (:affected)  (:temporary (:scs (non-descriptor-reg)) temp)  (:policy :fast-safe))(define-vop (fast-conditional/fixnum fast-conditional)  (:args (x :scs (any-reg))         (y :scs (any-reg)))  (:arg-types tagged-num tagged-num)  (:note "inline fixnum comparison"))(define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg)))  (:arg-types tagged-num (:constant (unsigned-byte-with-a-bite-out 6 4)))  (:info target not-p y))(define-vop (fast-conditional/signed fast-conditional)  (:args (x :scs (signed-reg))         (y :scs (signed-reg)))  (: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)))  (:arg-types signed-num (:constant (unsigned-byte-with-a-bite-out 8 1)))  (:info target not-p y))(define-vop (fast-conditional/unsigned fast-conditional)  (:args (x :scs (unsigned-reg))         (y :scs (unsigned-reg)))  (: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)))  (:arg-types unsigned-num (:constant (unsigned-byte-with-a-bite-out 8 1)))  (:info target not-p y))(defmacro define-conditional-vop (translate &rest generator)  `(progn     ,@(mapcar (lambda (suffix cost signed)                 (unless (and (member suffix '(/fixnum -c/fixnum))                              (eq translate 'eql))                   `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"                                                  translate suffix))                                 ,(intern                                   (format nil "~:@(FAST-CONDITIONAL~A~)"                                           suffix)))                      (:translate ,translate)                      (:generator ,cost                                  (let* ((signed ,signed)                                         (-c/fixnum ,(eq suffix '-c/fixnum))                                         (y (if -c/fixnum (fixnumize y) y)))                                    ,@generator)))))               '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)               '(3 2 5 4 5 4)               '(t t t t nil nil))))(define-conditional-vop <  (cond ((and signed (eql y 0))         (if not-p             (inst bge x target)             (inst blt x target)))        (t         (if signed             (inst cmplt x y temp)             (inst cmpult x y temp))         (if not-p             (inst beq temp target)             (inst bne temp target)))))(define-conditional-vop >  (cond ((and signed (eql y 0))         (if not-p             (inst ble x target)             (inst bgt x target)))        ((integerp y)         (let ((y (+ y (if -c/fixnum (fixnumize 1) 1))))           (if signed               (inst cmplt x y temp)               (inst cmpult x y temp))           (if not-p               (inst bne temp target)               (inst beq temp target))))        (t         (if signed             (inst cmplt y x temp)             (inst cmpult y x temp))         (if not-p             (inst beq temp target)             (inst bne temp target)))));;; EQL/FIXNUM is funny because the first arg can be of any type, not;;; just a known fixnum.(define-conditional-vop eql  (declare (ignore signed))  (when (integerp y)    (inst li y temp)    (setf y temp))  (inst cmpeq x y temp)  (if not-p      (inst beq temp target)      (inst bne temp target)));;; 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))         (y :scs (any-reg)))  (:arg-types tagged-num tagged-num)  (:note "inline fixnum comparison")  (:translate eql)  (:generator 3    (cond ((equal y zero-tn)           (if not-p               (inst bne x target)               (inst beq x target)))          (t           (inst cmpeq x y temp)           (if not-p               (inst beq temp target)               (inst bne temp target))))));;;(define-vop (generic-eql/fixnum fast-eql/fixnum)  (:args (x :scs (any-reg descriptor-reg))         (y :scs (any-reg)))  (:arg-types * tagged-num)  (:variant-cost 7))(define-vop (fast-eql-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg)))  (:arg-types tagged-num (:constant (signed-byte 6)))  (:temporary (:scs (non-descriptor-reg)) temp)  (:info target not-p y)  (:translate eql)  (:generator 2    (let ((y (cond ((eql y 0) zero-tn)                   (t                    (inst li (fixnumize y) temp)                    temp))))      (inst cmpeq x y temp)      (if not-p          (inst beq temp target)          (inst bne temp target)))));;;(define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)  (:args (x :scs (any-reg descriptor-reg)))  (:arg-types * (:constant (signed-byte 6)))  (:variant-cost 6));;;; 32-bit logical operations(define-vop (merge-bits)  (:translate merge-bits)  (:args (shift :scs (signed-reg unsigned-reg))         (prev :scs (unsigned-reg))         (next :scs (unsigned-reg)))  (:arg-types tagged-num unsigned-num unsigned-num)  (:temporary (:scs (unsigned-reg) :to (:result 0)) temp)  (:temporary (:scs (unsigned-reg) :to (:result 0) :target result) res)  (:results (result :scs (unsigned-reg)))  (:result-types unsigned-num)  (:policy :fast-safe)  (:generator 4    (let ((done (gen-label)))      (inst srl next shift res)      (inst beq shift done)      (inst subq zero-tn shift temp)      (inst sll prev temp temp)      (inst bis res temp res)      (emit-label done)      (move res result))))(define-vop (shift-towards-someplace)  (:policy :fast-safe)  (:args (num :scs (unsigned-reg))         (amount :scs (signed-reg)))  (:arg-types unsigned-num tagged-num)  (:results (r :scs (unsigned-reg)))  (:result-types unsigned-num))(define-vop (shift-towards-start shift-towards-someplace)  (:translate shift-towards-start)  (:note "SHIFT-TOWARDS-START")  (:temporary (:sc non-descriptor-reg) temp)  (:generator 1    (inst and amount #x1f temp)    (inst srl num temp r)))(define-vop (shift-towards-end shift-towards-someplace)  (:translate shift-towards-end)  (:note "SHIFT-TOWARDS-END")  (:temporary (:sc non-descriptor-reg) temp)  (:generator 1    (inst and amount #x1f temp)    (inst sll num temp r)));;;; bignum stuff(define-vop (bignum-length get-header-data)  (:translate sb!bignum:%bignum-length)  (:policy :fast-safe))(define-vop (bignum-set-length set-header-data)  (:translate sb!bignum:%bignum-set-length)  (:policy :fast-safe))(define-full-reffer bignum-ref * bignum-digits-offset other-pointer-lowtag  (unsigned-reg) unsigned-num sb!bignum:%bignum-ref)(define-full-setter bignum-set * bignum-digits-offset other-pointer-lowtag  (unsigned-reg) unsigned-num sb!bignum:%bignum-set #!+gengc nil)(define-vop (digit-0-or-plus)  (:translate sb!bignum:%digit-0-or-plusp)  (:policy :fast-safe)  (:args (digit :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:temporary (:sc non-descriptor-reg) temp)  (:conditional)  (:info target not-p)  (:generator 2    (inst sll digit 32 temp)    (if not-p        (inst blt temp target)        (inst bge temp target))))(define-vop (add-w/carry)  (:translate sb!bignum:%add-with-carry)  (:policy :fast-safe)  (:args (a :scs (unsigned-reg))         (b :scs (unsigned-reg))         (c :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num positive-fixnum)  (:results (result :scs (unsigned-reg) :from :load)            (carry :scs (unsigned-reg) :from :eval))  (:result-types unsigned-num positive-fixnum)  (:generator 5    (inst addq a b result)    (inst addq result c result)    (inst sra result 32 carry)    (inst mskll result 4 result)))(define-vop (sub-w/borrow)  (:translate sb!bignum:%subtract-with-borrow)  (:policy :fast-safe)  (:args (a :scs (unsigned-reg))         (b :scs (unsigned-reg))         (c :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num positive-fixnum)  (:results (result :scs (unsigned-reg) :from :load)            (borrow :scs (unsigned-reg) :from :eval))  (:result-types unsigned-num positive-fixnum)  (:generator 4    (inst xor c 1 result)    (inst subq a result result)    (inst subq result b result)    (inst srl result 63 borrow)    (inst xor borrow 1 borrow)    (inst mskll result 4 result)))(define-vop (bignum-mult-and-add-3-arg)  (:translate sb!bignum:%multiply-and-add)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg))         (y :scs (unsigned-reg))         (carry-in :scs (unsigned-reg) :to :save))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg))            (lo :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:generator 6    (inst mulq x y lo)    (inst addq lo carry-in lo)    (inst srl lo 32 hi)    (inst mskll lo 4 lo)))(define-vop (bignum-mult-and-add-4-arg)  (:translate sb!bignum:%multiply-and-add)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg))         (y :scs (unsigned-reg))         (prev :scs (unsigned-reg))         (carry-in :scs (unsigned-reg) :to :save))  (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg))            (lo :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:generator 9    (inst mulq x y lo)    (inst addq lo prev lo)    (inst addq lo carry-in lo)    (inst srl lo 32 hi)    (inst mskll lo 4 lo)))(define-vop (bignum-mult)  (:translate sb!bignum:%multiply)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg))         (y :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg))            (lo :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:generator 3    (inst mulq x y lo)    (inst srl lo 32 hi)    (inst mskll lo 4 lo)))(define-vop (bignum-lognot)  (:translate sb!bignum:%lognot)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (r :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 1    (inst not x r)    (inst mskll r 4 r)))(define-vop (fixnum-to-digit)  (:translate sb!bignum:%fixnum-to-digit)  (:policy :fast-safe)  (:args (fixnum :scs (any-reg)))  (:arg-types tagged-num)  (:results (digit :scs (unsigned-reg)))  (:result-types unsigned-num)  (:generator 1    (inst sra fixnum n-fixnum-tag-bits digit)))(define-vop (bignum-floor)  (:translate sb!bignum:%floor)  (:policy :fast-safe)  (:args (num-high :scs (unsigned-reg))         (num-low :scs (unsigned-reg))         (denom-arg :scs (unsigned-reg) :target denom))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:temporary (:scs (unsigned-reg) :from (:argument 2)) denom)  (:temporary (:scs (unsigned-reg) :from (:eval 0)) temp)  (:results (quo :scs (unsigned-reg) :from (:eval 0))            (rem :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num unsigned-num)  (:generator 325 ; number of inst assuming targeting works.    (inst sll num-high 32 rem)    (inst bis rem num-low rem)    (inst sll denom-arg 32 denom)    (inst cmpule denom rem quo)    (inst beq quo shift1)    (inst subq rem denom rem)    SHIFT1    (dotimes (i 32)      (let ((shift2 (gen-label)))        (inst srl denom 1 denom)        (inst cmpule denom rem temp)        (inst sll quo 1 quo)        (inst beq temp shift2)        (inst subq rem denom rem)        (inst bis quo 1 quo)        (emit-label shift2)))))(define-vop (signify-digit)  (:translate sb!bignum:%fixnum-digit-with-correct-sign)  (:policy :fast-safe)  (:args (digit :scs (unsigned-reg) :target res))  (:arg-types unsigned-num)  (:results (res :scs (any-reg signed-reg)))  (:result-types signed-num)  (:generator 2    (sc-case res      (any-reg       (inst sll digit 34 res)       (inst sra res 32 res))      (signed-reg       (inst sll digit 32 res)       (inst sra res 32 res)))))(define-vop (digit-ashr)  (:translate sb!bignum:%ashr)  (:policy :fast-safe)  (:args (digit :scs (unsigned-reg))         (count :scs (unsigned-reg)))  (:arg-types unsigned-num positive-fixnum)  (:results (result :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num)  (:generator 1    (inst sll digit 32 result)    (inst sra result count result)    (inst srl result 32 result)))(define-vop (digit-lshr digit-ashr)  (:translate sb!bignum:%digit-logical-shift-right)  (:generator 1    (inst srl digit count result)))(define-vop (digit-ashl digit-ashr)  (:translate sb!bignum:%ashl)  (:generator 1    (inst sll digit count result)));;;; static functions(define-static-fun two-arg-gcd (x y) :translate gcd)(define-static-fun two-arg-lcm (x y) :translate lcm)(define-static-fun two-arg-+ (x y) :translate +)(define-static-fun two-arg-- (x y) :translate -)(define-static-fun two-arg-* (x y) :translate *)(define-static-fun two-arg-/ (x y) :translate /)(define-static-fun two-arg-< (x y) :translate <)(define-static-fun two-arg-<= (x y) :translate <=)(define-static-fun two-arg-> (x y) :translate >)(define-static-fun two-arg->= (x y) :translate >=)(define-static-fun two-arg-= (x y) :translate =)(define-static-fun two-arg-/= (x y) :translate /=)(define-static-fun %negate (x) :translate %negate)(define-static-fun two-arg-and (x y) :translate logand)(define-static-fun two-arg-ior (x y) :translate logior)(define-static-fun two-arg-xor (x y) :translate logxor)(define-static-fun two-arg-eqv (x y) :translate logeqv)

⌨️ 快捷键说明

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