📄 arith.lisp
字号:
'sb!vm::%lea-smod30))#+sb-xc-host(progn (defun sb!vm::%lea-mod32 (base index scale disp) (ldb (byte 32 0) (%lea base index scale disp))) (defun sb!vm::%lea-smod30 (base index scale disp) (mask-signed-field 30 (%lea base index scale disp))))#-sb-xc-host(progn (defun sb!vm::%lea-mod32 (base index scale disp) (let ((base (logand base #xffffffff)) (index (logand index #xffffffff))) ;; can't use modular version of %LEA, as we only have VOPs for ;; constant SCALE and DISP. (ldb (byte 32 0) (+ base (* index scale) disp)))) (defun sb!vm::%lea-smod30 (base index scale disp) (let ((base (mask-signed-field 30 base)) (index (mask-signed-field 30 index))) ;; can't use modular version of %LEA, as we only have VOPs for ;; constant SCALE and DISP. (mask-signed-field 30 (+ base (* index scale) disp)))))(in-package "SB!VM")(define-vop (%lea-mod32/unsigned=>unsigned %lea/unsigned=>unsigned) (:translate %lea-mod32))(define-vop (%lea-smod30/fixnum=>fixnum %lea/fixnum=>fixnum) (:translate %lea-smod30));;; logical operations(define-modular-fun lognot-mod32 (x) lognot :untagged nil 32)(define-vop (lognot-mod32/word=>unsigned) (:translate lognot-mod32) (:args (x :scs (unsigned-reg signed-reg unsigned-stack signed-stack) :target r :load-if (not (and (or (sc-is x unsigned-stack) (sc-is x signed-stack)) (or (sc-is r unsigned-stack) (sc-is r signed-stack)) (location= x r))))) (:arg-types unsigned-num) (:results (r :scs (unsigned-reg) :load-if (not (and (or (sc-is x unsigned-stack) (sc-is x signed-stack)) (or (sc-is r unsigned-stack) (sc-is r signed-stack)) (sc-is r unsigned-stack) (location= x r))))) (:result-types unsigned-num) (:policy :fast-safe) (:generator 1 (move r x) (inst not r)))(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 lognor (x y) `(lognot (logior ,x ,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-reffer+offset bignum-ref-with-offset * bignum-digits-offset other-pointer-lowtag (unsigned-reg) unsigned-num sb!bignum:%bignum-ref-with-offset)(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 3 (inst or digit digit) (inst jmp (if not-p :s :ns) target)));;; For add and sub with carry the sc of carry argument is any-reg so;;; that it may be passed as a fixnum or word and thus may be 0, 1, or;;; 4. This is easy to deal with and may save a fixnum-word;;; conversion.(define-vop (add-w/carry) (:translate sb!bignum:%add-with-carry) (:policy :fast-safe) (:args (a :scs (unsigned-reg) :target result) (b :scs (unsigned-reg unsigned-stack) :to :eval) (c :scs (any-reg) :target temp)) (:arg-types unsigned-num unsigned-num positive-fixnum) (:temporary (:sc any-reg :from (:argument 2) :to :eval) temp) (:results (result :scs (unsigned-reg) :from (:argument 0)) (carry :scs (unsigned-reg))) (:result-types unsigned-num positive-fixnum) (:generator 4 (move result a) (move temp c) (inst neg temp) ; Set the carry flag to 0 if c=0 else to 1 (inst adc result b) (inst mov carry 0) (inst adc carry carry)));;; Note: the borrow is 1 for no borrow and 0 for a borrow, the opposite;;; of the x86 convention.(define-vop (sub-w/borrow) (:translate sb!bignum:%subtract-with-borrow) (:policy :fast-safe) (:args (a :scs (unsigned-reg) :to :eval :target result) (b :scs (unsigned-reg unsigned-stack) :to :result) (c :scs (any-reg control-stack))) (:arg-types unsigned-num unsigned-num positive-fixnum) (:results (result :scs (unsigned-reg) :from :eval) (borrow :scs (unsigned-reg))) (:result-types unsigned-num positive-fixnum) (:generator 5 (inst cmp c 1) ; Set the carry flag to 1 if c=0 else to 0 (move result a) (inst sbb result b) (inst mov borrow 1) (inst sbb borrow 0)))(define-vop (bignum-mult-and-add-3-arg) (:translate sb!bignum:%multiply-and-add) (:policy :fast-safe) (:args (x :scs (unsigned-reg) :target eax) (y :scs (unsigned-reg unsigned-stack)) (carry-in :scs (unsigned-reg unsigned-stack))) (:arg-types unsigned-num unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0) :to (:result 1) :target lo) eax) (:temporary (:sc unsigned-reg :offset edx-offset :from (:argument 1) :to (:result 0) :target hi) edx) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 20 (move eax x) (inst mul eax y) (inst add eax carry-in) (inst adc edx 0) (move hi edx) (move lo eax)))(define-vop (bignum-mult-and-add-4-arg) (:translate sb!bignum:%multiply-and-add) (:policy :fast-safe) (:args (x :scs (unsigned-reg) :target eax) (y :scs (unsigned-reg unsigned-stack)) (prev :scs (unsigned-reg unsigned-stack)) (carry-in :scs (unsigned-reg unsigned-stack))) (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0) :to (:result 1) :target lo) eax) (:temporary (:sc unsigned-reg :offset edx-offset :from (:argument 1) :to (:result 0) :target hi) edx) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 20 (move eax x) (inst mul eax y) (inst add eax prev) (inst adc edx 0) (inst add eax carry-in) (inst adc edx 0) (move hi edx) (move lo eax)))(define-vop (bignum-mult) (:translate sb!bignum:%multiply) (:policy :fast-safe) (:args (x :scs (unsigned-reg) :target eax) (y :scs (unsigned-reg unsigned-stack))) (:arg-types unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0) :to (:result 1) :target lo) eax) (:temporary (:sc unsigned-reg :offset edx-offset :from (:argument 1) :to (:result 0) :target hi) edx) (:results (hi :scs (unsigned-reg)) (lo :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 20 (move eax x) (inst mul eax y) (move hi edx) (move lo eax)))(define-vop (bignum-lognot lognot-mod32/word=>unsigned) (:translate sb!bignum:%lognot))(define-vop (fixnum-to-digit) (:translate sb!bignum:%fixnum-to-digit) (:policy :fast-safe) (:args (fixnum :scs (any-reg control-stack) :target digit)) (:arg-types tagged-num) (:results (digit :scs (unsigned-reg) :load-if (not (and (sc-is fixnum control-stack) (sc-is digit unsigned-stack) (location= fixnum digit))))) (:result-types unsigned-num) (:generator 1 (move digit fixnum) (inst sar digit 2)))(define-vop (bignum-floor) (:translate sb!bignum:%floor) (:policy :fast-safe) (:args (div-high :scs (unsigned-reg) :target edx) (div-low :scs (unsigned-reg) :target eax) (divisor :scs (unsigned-reg unsigned-stack))) (:arg-types unsigned-num unsigned-num unsigned-num) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 1) :to (:result 0) :target quo) eax) (:temporary (:sc unsigned-reg :offset edx-offset :from (:argument 0) :to (:result 1) :target rem) edx) (:results (quo :scs (unsigned-reg)) (rem :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) (:generator 300 (move edx div-high) (move eax div-low) (inst div eax divisor) (move quo eax) (move rem edx)))(define-vop (signify-digit) (:translate sb!bignum:%fixnum-digit-with-correct-sign) (:policy :fast-safe) (:args (digit :scs (unsigned-reg unsigned-stack) :target res)) (:arg-types unsigned-num) (:results (res :scs (any-reg signed-reg) :load-if (not (and (sc-is digit unsigned-stack) (sc-is res control-stack signed-stack) (location= digit res))))) (:result-types signed-num) (:generator 1 (move res digit) (when (sc-is res any-reg control-stack) (inst shl res 2))))(define-vop (digit-ashr) (:translate sb!bignum:%ashr) (:policy :fast-safe) (:args (digit :scs (unsigned-reg unsigned-stack) :target result) (count :scs (unsigned-reg) :target ecx)) (:arg-types unsigned-num positive-fixnum) (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx) (:results (result :scs (unsigned-reg) :from (:argument 0) :load-if (not (and (sc-is result unsigned-stack) (location= digit result))))) (:result-types unsigned-num) (:generator 2 (move result digit) (move ecx count) (inst sar result :cl)))(define-vop (digit-ashr/c) (:translate sb!bignum:%ashr) (:policy :fast-safe) (:args (digit :scs (unsigned-reg unsigned-stack) :target result)) (:arg-types unsigned-num (:constant (integer 0 31))) (:info count) (:results (result :scs (unsigned-reg) :from (:argument 0) :load-if (not (and (sc-is result unsigned-stack) (location= digit result))))) (:result-types unsigned-num) (:generator 1 (move result digit) (inst sar result count)))(define-vop (digit-lshr digit-ashr) (:translate sb!bignum:%digit-logical-shift-right) (:generator 1 (move result digit) (move ecx count) (inst shr result :cl)))(define-vop (digit-ashl digit-ashr) (:translate sb!bignum:%ashl) (:generator 1 (move result digit) (move ecx count) (inst shl result :cl)));;;; static functions(define-static-fun two-arg-/ (x y) :translate /)(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-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);;; Support for the Mersenne Twister, MT19937, random number generator;;; due to Matsumoto and Nishimura.;;;;;; Makoto Matsumoto and T. Nishimura, "Mersenne twister: A;;; 623-dimensionally equidistributed uniform pseudorandom number;;; generator.", ACM Transactions on Modeling and Computer Simulation,;;; 1997, to appear.;;;;;; State:;;; 0-1: Constant matrix A. [0, #x9908b0df] (not used here);;; 2: Index; init. to 1.;;; 3-626: State.(defknown random-mt19937 ((simple-array (unsigned-byte 32) (*))) (unsigned-byte 32) ())(define-vop (random-mt19937) (:policy :fast-safe) (:translate random-mt19937) (:args (state :scs (descriptor-reg) :to :result)) (:arg-types simple-array-unsigned-byte-32) (:temporary (:sc unsigned-reg :from (:eval 0) :to :result) k) (:temporary (:sc unsigned-r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -