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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
  (: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 cmp shift)      (inst b :eq done)      (inst srl res next shift)      (inst sub temp zero-tn shift)      (inst sll temp prev temp)      (inst or res temp)      (emit-label done)      (move result res))))(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")  (:generator 1    (inst sll r num amount)))(define-vop (shift-towards-end shift-towards-someplace)  (:translate shift-towards-end)  (:note "shift-towards-end")  (:generator 1    (inst srl r num amount)));;;; 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-vop (bignum-ref word-index-ref)  (:variant bignum-digits-offset other-pointer-lowtag)  (:translate sb!bignum:%bignum-ref)  (:results (value :scs (unsigned-reg)))  (:result-types unsigned-num))(define-vop (bignum-set word-index-set)  (:variant bignum-digits-offset other-pointer-lowtag)  (:translate sb!bignum:%bignum-set)  (:args (object :scs (descriptor-reg))         (index :scs (any-reg immediate zero))         (value :scs (unsigned-reg)))  (:arg-types t positive-fixnum unsigned-num)  (:results (result :scs (unsigned-reg)))  (:result-types unsigned-num))(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)  (:results (result :scs (descriptor-reg)))  (:guard (not (member :sparc-v9 *backend-subfeatures*)))  (:generator 3    (let ((done (gen-label)))      (inst cmp digit)      (inst b :lt done)      (move result null-tn)      (load-symbol result t)      (emit-label done))))(define-vop (v9-digit-0-or-plus-cmove)  (:translate sb!bignum:%digit-0-or-plusp)  (:policy :fast-safe)  (:args (digit :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (result :scs (descriptor-reg)))  (:guard (member :sparc-v9 *backend-subfeatures*))  (:generator 3    (inst cmp digit)    (load-symbol result t)    (inst cmove :lt result null-tn)));; This doesn't work?#+nil(define-vop (v9-digit-0-or-plus-movr)  (:translate sb!bignum:%digit-0-or-plusp)  (:policy :fast-safe)  (:args (digit :scs (unsigned-reg)))  (:arg-types unsigned-num)  (:results (result :scs (descriptor-reg)))  (:temporary (:scs (descriptor-reg)) temp)  (:guard #!+:sparc-v9 t #!-:sparc-v9 nil)  (:generator 2    (load-symbol temp t)    (inst movr result null-tn digit :lz)    (inst movr result temp digit :gez)))(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 (any-reg)))  (:arg-types unsigned-num unsigned-num positive-fixnum)  (:results (result :scs (unsigned-reg))            (carry :scs (unsigned-reg)))  (:result-types unsigned-num positive-fixnum)  (:generator 3    (inst addcc zero-tn c -1)    (inst addxcc result a b)    (inst addx carry zero-tn zero-tn)))(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 (any-reg)))  (:arg-types unsigned-num unsigned-num positive-fixnum)  (:results (result :scs (unsigned-reg))            (borrow :scs (unsigned-reg)))  (:result-types unsigned-num positive-fixnum)  (:generator 4    (inst subcc zero-tn c 1)    (inst subxcc result a b)    (inst addx borrow zero-tn zero-tn)    (inst xor borrow 1)));;; EMIT-MULTIPLY -- This is used both for bignum stuff and in assembly;;; routines.;;;(defun emit-multiply (multiplier multiplicand result-high result-low)  "Emit code to multiply MULTIPLIER with MULTIPLICAND, putting the result  in RESULT-HIGH and RESULT-LOW.  KIND is either :signed or :unsigned.  Note: the lifetimes of MULTIPLICAND and RESULT-HIGH overlap."  (declare (type tn multiplier result-high result-low)           (type (or tn (signed-byte 13)) multiplicand))  ;; It seems that emit-multiply is only used to do an unsigned  ;; multiply, so the code only does an unsigned multiply.  (cond    ((member :sparc-64 *backend-subfeatures*)     ;; Take advantage of V9's 64-bit multiplier.     ;;     ;; Make sure the multiplier and multiplicand are really     ;; unsigned 64-bit numbers.     (inst srl multiplier 0)     (inst srl multiplicand 0)     ;; Multiply the two numbers and put the result in     ;; result-high.  Copy the low 32-bits to result-low.  Then     ;; shift result-high so the high 32-bits end up in the low     ;; 32-bits.     (inst mulx result-high multiplier multiplicand)     (inst move result-low result-high)     (inst srax result-high 32))    ((or (member :sparc-v8 *backend-subfeatures*)         (member :sparc-v9 *backend-subfeatures*))     ;; V8 has a multiply instruction.  This should also work for     ;; the V9, but umul and the Y register is deprecated on the     ;; V9.     (inst umul result-low multiplier multiplicand)     (inst rdy result-high))    (t     (let ((label (gen-label)))       (inst wry multiplier)       (inst andcc result-high zero-tn)       ;; Note: we can't use the Y register until three insts       ;; after it's written.       (inst nop)       (inst nop)       (dotimes (i 32)         (inst mulscc result-high multiplicand))       (inst mulscc result-high zero-tn)       (inst cmp multiplicand)       (inst b :ge label)       (inst nop)       (inst add result-high multiplier)       (emit-label label)       (inst rdy result-low)))))(define-vop (bignum-mult-and-add-3-arg)  (:translate sb!bignum:%multiply-and-add)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg) :to (:eval 1))         (y :scs (unsigned-reg) :to (:eval 1))         (carry-in :scs (unsigned-reg) :to (:eval 2)))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg) :from (:eval 0))            (lo :scs (unsigned-reg) :from (:eval 1)))  (:result-types unsigned-num unsigned-num)  (:generator 40    (emit-multiply x y hi lo)    (inst addcc lo carry-in)    (inst addx hi zero-tn)))(define-vop (bignum-mult-and-add-4-arg)  (:translate sb!bignum:%multiply-and-add)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg) :to (:eval 1))         (y :scs (unsigned-reg) :to (:eval 1))         (prev :scs (unsigned-reg) :to (:eval 2))         (carry-in :scs (unsigned-reg) :to (:eval 2)))  (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg) :from (:eval 0))            (lo :scs (unsigned-reg) :from (:eval 1)))  (:result-types unsigned-num unsigned-num)  (:generator 40    (emit-multiply x y hi lo)    (inst addcc lo carry-in)    (inst addx hi zero-tn)    (inst addcc lo prev)    (inst addx hi zero-tn)))(define-vop (bignum-mult)  (:translate sb!bignum:%multiply)  (:policy :fast-safe)  (:args (x :scs (unsigned-reg) :to (:result 1))         (y :scs (unsigned-reg) :to (:result 1)))  (:arg-types unsigned-num unsigned-num)  (:results (hi :scs (unsigned-reg))            (lo :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:generator 40    (emit-multiply x y hi lo)))(define-vop (bignum-lognot lognot-mod32/unsigned=>unsigned)  (:translate sb!bignum:%lognot))(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 digit fixnum n-fixnum-tag-bits)))(define-vop (bignum-floor)  (:translate sb!bignum:%floor)  (:policy :fast-safe)  (:args (div-high :scs (unsigned-reg) :target rem)         (div-low :scs (unsigned-reg) :target quo)         (divisor :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:results (quo :scs (unsigned-reg) :from (:argument 1))            (rem :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num unsigned-num)  (:generator 300    (move rem div-high)    (move quo div-low)    (dotimes (i 33)      (let ((label (gen-label)))        (inst cmp rem divisor)        (inst b :ltu label)        (inst addxcc quo quo)        (inst sub rem divisor)        (emit-label label)        (unless (= i 32)          (inst addx rem rem))))    (inst not quo)))(define-vop (bignum-floor-v8)  (:translate sb!bignum:%floor)  (:policy :fast-safe)  (:args (div-high :scs (unsigned-reg) :target rem)         (div-low :scs (unsigned-reg) :target quo)         (divisor :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:results (quo :scs (unsigned-reg) :from (:argument 1))            (rem :scs (unsigned-reg) :from (:argument 0)))  (:result-types unsigned-num unsigned-num)  (:temporary (:scs (unsigned-reg) :target quo) q)  ;; This vop is for a v8 or v9, provided we're also not using  ;; sparc-64, for which there a special sparc-64 vop.  (:guard (or (member :sparc-v8 *backend-subfeatures*)              (member :sparc-v9 *backend-subfeatures*)))  (:generator 15    (inst wry div-high)    (inst nop)    (inst nop)    (inst nop)    ;; Compute the quotient [Y, div-low] / divisor    (inst udiv q div-low divisor)    ;; Compute the remainder.  The high part of the result is in the Y    ;; register.    (inst umul rem q divisor)    (inst sub rem div-low rem)    (unless (location= quo q)      (move quo q))))(define-vop (bignum-floor-v9)  (:translate sb!bignum:%floor)  (:policy :fast-safe)  (:args (div-high :scs (unsigned-reg))         (div-low :scs (unsigned-reg))         (divisor :scs (unsigned-reg) :to (:result 1)))  (:arg-types unsigned-num unsigned-num unsigned-num)  (:temporary (:sc unsigned-reg :from (:argument 0)) dividend)  (:results (quo :scs (unsigned-reg))            (rem :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:guard (member :sparc-64 *backend-subfeatures*))  (:generator 5    ;; Set dividend to be div-high and div-low    (inst sllx dividend div-high 32)    (inst add dividend div-low)    ;; Compute quotient    (inst udivx quo dividend divisor)    ;; Compute the remainder    (inst mulx rem quo divisor)    (inst sub rem dividend rem)))(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 1    (sc-case res      (any-reg       (inst sll res digit n-fixnum-tag-bits))      (signed-reg       (move res digit)))))(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)))  (:result-types unsigned-num)  (:generator 1    (inst sra result digit count)))(define-vop (digit-lshr digit-ashr)  (:translate sb!bignum:%digit-logical-shift-right)  (:generator 1    (inst srl result digit count)))(define-vop (digit-ashl digit-ashr)  (:translate sb!bignum:%ashl)  (:generator 1    (inst sll result digit count)));;;; 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)(in-package "SB!C")(deftransform * ((x y)                 ((unsigned-byte 32) (constant-arg (unsigned-byte 32)))                 (unsigned-byte 32))  "recode as shifts and adds"  (let ((y (lvar-value y)))    (multiple-value-bind (result adds shifts)        (ub32-strength-reduce-constant-multiply 'x y)      (cond        ;; we assume, perhaps foolishly, that good SPARCs don't have an        ;; issue with multiplications.  (Remember that there's a        ;; different transform for converting x*2^k to a shift).        ((member :sparc-64 *backend-subfeatures*) (give-up-ir1-transform))        ((or (member :sparc-v9 *backend-subfeatures*)             (member :sparc-v8 *backend-subfeatures*))         ;; breakeven point as measured by Raymond Toy         (when (> (+ adds shifts) 9)           (give-up-ir1-transform))))      (or result 0))))

⌨️ 快捷键说明

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