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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
(define-vop (%lea-mod64/unsigned=>unsigned             %lea/unsigned=>unsigned)  (:translate %lea-mod64))(define-vop (%lea-smod61/fixnum=>fixnum             %lea/fixnum=>fixnum)  (:translate %lea-smod61));;; logical operations(define-modular-fun lognot-mod64 (x) lognot :untagged nil 64)(define-vop (lognot-mod64/unsigned=>unsigned)  (:translate lognot-mod64)  (:args (x :scs (unsigned-reg unsigned-stack) :target r            :load-if (not (and (sc-is x unsigned-stack)                               (sc-is r unsigned-stack)                               (location= x r)))))  (:arg-types unsigned-num)  (:results (r :scs (unsigned-reg)               :load-if (not (and (sc-is x unsigned-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;;; 8. 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-64 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-mod64/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 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 3)))(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 3))))(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 63)))  (: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)(in-package "SB!C")(defun *-transformer (y)  (cond    ((= y (ash 1 (integer-length y)))     ;; there's a generic transform for y = 2^k     (give-up-ir1-transform))    ((member y '(3 5 9))     ;; we can do these multiplications directly using LEA     `(%lea x x ,(1- y) 0))    (t     ;; A normal 64-bit multiplication takes 4 cycles on Athlon 64/Opteron.     ;; Optimizing multiplications (other than the above cases) to     ;; shifts/adds/leas gives a maximum improvement of 1 cycle, but requires     ;; quite a lot of hairy code.     (give-up-ir1-transform))))(deftransform * ((x y)                 ((unsigned-byte 64) (constant-arg (unsigned-byte 64)))                 (unsigned-byte 64))  "recode as leas, shifts and adds"  (let ((y (lvar-value y)))    (*-transformer y)))(deftransform sb!vm::*-mod64    ((x y) ((unsigned-byte 64) (constant-arg (unsigned-byte 64)))     (unsigned-byte 64))  "recode as leas, shifts and adds"  (let ((y (lvar-value y)))    (*-transformer y)))(deftransform * ((x y)                 ((signed-byte 61) (constant-arg (unsigned-byte 64)))                 (signed-byte 61))  "recode as leas, shifts and adds"  (let ((y (lvar-value y)))    (*-transformer y)))(deftransform sb!vm::*-smod61    ((x y) ((signed-byte 61) (constant-arg (unsigned-byte 64)))     (signed-byte 61))  "recode as leas, shifts and adds"  (let ((y (lvar-value y)))    (*-transformer y)))

⌨️ 快捷键说明

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