📄 arith.lisp
字号:
(inst b? (if not-p :ne :eq) target)));;;(define-vop (generic-eql-c/fixnum fast-eql-c/fixnum) (:arg-types * (:constant (signed-byte 11))) (: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 cmpwi shift 0) (inst beq done) (inst srw res next shift) (inst sub temp zero-tn shift) (inst slw temp prev temp) (inst or res 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 rlwinm amount amount 0 27 31) (inst slw r num amount)))(define-vop (shift-towards-end shift-towards-someplace) (:translate shift-towards-end) (:note "shift-towards-end") (:generator 1 (inst rlwinm amount amount 0 27 31) (inst srw 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))) (:generator 3 (let ((done (gen-label))) (inst cmpwi digit 0) (move result null-tn) (inst blt done) (load-symbol result t) (emit-label done))))(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) (:temporary (:scs (unsigned-reg)) temp) (:results (result :scs (unsigned-reg)) (carry :scs (unsigned-reg))) (:result-types unsigned-num positive-fixnum) (:generator 3 (inst addic temp c -1) (inst adde result a b) (inst addze carry 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) (:temporary (:scs (unsigned-reg)) temp) (:results (result :scs (unsigned-reg)) (borrow :scs (unsigned-reg))) (:result-types unsigned-num positive-fixnum) (:generator 4 (inst addic temp c -1) (inst sube result a b) (inst addze borrow zero-tn)))(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 (:eval 1))) (:arg-types unsigned-num unsigned-num unsigned-num) (:temporary (:scs (unsigned-reg) :to (:result 0) :target hi) hi-temp) (:temporary (:scs (unsigned-reg) :from (:eval 0) :to (:result 1) :target lo) lo-temp) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 40 (inst mulhwu hi-temp x y) (inst mullw lo-temp x y) (inst addc lo lo-temp carry-in) (inst addze hi hi-temp)))(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) :to (:eval 1)) (carry-in :scs (unsigned-reg) :to (:eval 1))) (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num) (:temporary (:scs (unsigned-reg) :to (:result 0) :target hi) hi-temp) (:temporary (:scs (unsigned-reg) :from (:eval 0) :to (:result 1) :target lo) lo-temp) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 40 (inst mulhwu hi-temp x y) (inst mullw lo-temp x y) (inst addc lo-temp lo-temp carry-in) (inst addze hi-temp hi-temp) (inst addc lo lo-temp prev) (inst addze hi hi-temp)))(define-vop (bignum-mult) (:translate sb!bignum:%multiply) (:policy :fast-safe) (:args (x :scs (unsigned-reg) :to (:eval 1)) (y :scs (unsigned-reg) :to (:eval 1))) (:arg-types unsigned-num unsigned-num) (:results (hi :scs (unsigned-reg) :from (:eval 1)) (lo :scs (unsigned-reg) :from (:eval 0))) (:result-types unsigned-num unsigned-num) (:generator 40 (inst mullw lo x y) (inst mulhwu hi x y)))(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 srawi digit fixnum 2)))(define-vop (bignum-floor) (:translate sb!bignum:%floor) (:policy :fast-safe) (:args (num-high :scs (unsigned-reg) :target rem) (num-low :scs (unsigned-reg) :target rem-low) (denom :scs (unsigned-reg) :to (:eval 1))) (:arg-types unsigned-num unsigned-num unsigned-num) (:temporary (:scs (unsigned-reg) :from (:argument 1)) rem-low) (: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. (move rem num-high) (move rem-low num-low) (flet ((maybe-subtract (&optional (guess temp)) (inst subi temp guess 1) (inst and temp temp denom) (inst sub rem rem temp)) (sltu (res x y) (inst subfc res y x) (inst subfe res res res) (inst neg res res))) (sltu quo rem denom) (maybe-subtract quo) (dotimes (i 32) (inst slwi rem rem 1) (inst srwi temp rem-low 31) (inst or rem rem temp) (inst slwi rem-low rem-low 1) (sltu temp rem denom) (inst slwi quo quo 1) (inst or quo quo temp) (maybe-subtract))) (inst not quo quo)))#|(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 (inst mtmq div-low) (inst div quo div-high divisor) (inst mfmq 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 slwi res digit 2)) (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 sraw result digit count)))(define-vop (digit-lshr digit-ashr) (:translate sb!bignum:%digit-logical-shift-right) (:generator 1 (inst srw result digit count)))(define-vop (digit-ashl digit-ashr) (:translate sb!bignum:%ashl) (:generator 1 (inst slw result digit count)));;;; Static funs.(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 ((typep y '(signed-byte 16)) ;; a mulli instruction has a latency of 5. (when (> (+ adds shifts) 4) (give-up-ir1-transform))) (t ;; a mullw instruction also has a latency of 5, plus two ;; instructions (in general) to load the immediate into a ;; register. (when (> (+ adds shifts) 6) (give-up-ir1-transform)))) (or result 0))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -