📄 arith.lisp
字号:
(:translate shift-towards-start) (:note "SHIFT-TOWARDS-START") (:generator 1 (ecase *backend-byte-order* (:big-endian (inst sll r num amount)) (:little-endian (inst srl r num amount)))))(define-vop (shift-towards-end shift-towards-someplace) (:translate shift-towards-end) (:note "SHIFT-TOWARDS-END") (:generator 1 (ecase *backend-byte-order* (:big-endian (inst srl r num amount)) (:little-endian (inst sll r num amount)))));;;; Modular arithmetic(define-modular-fun +-mod32 (x y) + :untagged nil 32)(define-vop (fast-+-mod32/unsigned=>unsigned fast-+/unsigned=>unsigned) (:translate +-mod32))(define-vop (fast-+-mod32-c/unsigned=>unsigned fast-+-c/unsigned=>unsigned) (:translate +-mod32))(define-modular-fun --mod32 (x y) - :untagged nil 32)(define-vop (fast---mod32/unsigned=>unsigned fast--/unsigned=>unsigned) (:translate --mod32))(define-vop (fast---mod32-c/unsigned=>unsigned fast---c/unsigned=>unsigned) (:translate --mod32))(define-vop (fast-ash-left-mod32-c/unsigned=>unsigned fast-ash-c/unsigned=>unsigned) (:translate ash-left-mod32))(define-vop (fast-ash-left-mod32/unsigned=>unsigned fast-ash-left/unsigned=>unsigned))(deftransform ash-left-mod32 ((integer count) ((unsigned-byte 32) (unsigned-byte 5))) (when (sb!c::constant-lvar-p count) (sb!c::give-up-ir1-transform)) '(%primitive fast-ash-left-mod32/unsigned=>unsigned integer count));;; logical operations(define-modular-fun lognot-mod32 (x) lognot :untagged nil 32)(define-vop (lognot-mod32/unsigned=>unsigned) (:translate lognot-mod32) (:args (x :scs (unsigned-reg))) (:arg-types unsigned-num) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:policy :fast-safe) (:generator 1 (inst nor r x zero-tn)))(define-modular-fun lognor-mod32 (x y) lognor :untagged nil 32)(define-vop (fast-lognor-mod32/unsigned=>unsigned fast-lognor/unsigned=>unsigned) (:translate lognor-mod32))(define-source-transform logeqv (&rest args) (if (oddp (length args)) `(logxor ,@args) `(lognot (logxor ,@args))))(define-source-transform logandc1 (x y) `(logand (lognot ,x) ,y))(define-source-transform logandc2 (x y) `(logand ,x (lognot ,y)))(define-source-transform logorc1 (x y) `(logior (lognot ,x) ,y))(define-source-transform logorc2 (x y) `(logior ,x (lognot ,y)))(define-source-transform lognand (x y) `(lognot (logand ,x ,y)));;;; 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)(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) (:conditional) (:info target not-p) (:generator 2 (if not-p (inst bltz digit target) (inst bgez digit target)) (inst nop)))(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) :to (:result 0) :target result) res) (:results (result :scs (unsigned-reg)) (carry :scs (unsigned-reg) :from :eval)) (:result-types unsigned-num positive-fixnum) (:temporary (:scs (non-descriptor-reg)) temp) (:generator 5 (let ((carry-in (gen-label)) (done (gen-label))) (inst bne c carry-in) (inst addu res a b) (inst b done) (inst sltu carry res b) (emit-label carry-in) (inst addu res 1) (inst nor temp a zero-tn) (inst sltu carry b temp) (inst xor carry 1) (emit-label done) (move result res))))(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) :to (:result 0) :target result) res) (:results (result :scs (unsigned-reg)) (borrow :scs (unsigned-reg) :from :eval)) (:result-types unsigned-num positive-fixnum) (:generator 4 (let ((no-borrow-in (gen-label)) (done (gen-label))) (inst bne c no-borrow-in) (inst subu res a b) (inst subu res 1) (inst b done) (inst sltu borrow b a) (emit-label no-borrow-in) (inst sltu borrow a b) (inst xor borrow 1) (emit-label done) (move result res))))(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) (:temporary (:scs (unsigned-reg) :from (:argument 1)) temp) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 6 (inst multu x y) (inst mflo temp) (inst addu lo temp carry-in) (inst sltu temp lo carry-in) (inst mfhi hi) (inst addu 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)) (carry-in :scs (unsigned-reg) :to :save)) (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num) (:temporary (:scs (unsigned-reg) :from (:argument 2)) temp) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 9 (inst multu x y) (inst addu lo prev carry-in) (inst sltu temp lo carry-in) (inst mfhi hi) (inst addu hi temp) (inst mflo temp) (inst addu lo temp) (inst sltu temp lo temp) (inst addu hi temp)))(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 multu x y) (inst mflo lo) (inst mfhi hi)))(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 (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 subu temp guess 1) (inst and temp denom) (inst subu rem temp))) (inst sltu quo rem denom) (maybe-subtract quo) (dotimes (i 32) (inst sll rem 1) (inst srl temp rem-low 31) (inst or rem temp) (inst sll rem-low 1) (inst sltu temp rem denom) (inst sll quo 1) (inst or quo temp) (maybe-subtract))) (inst nor quo zero-tn)))(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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -