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

📄 arith.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
  (:arg-types signed-num)  (:results (res :scs (any-reg)))  (:result-types positive-fixnum)  (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift)  (:generator 30    (let ((loop (gen-label))          (test (gen-label)))      (move shift arg)      (inst bgez shift test)      (move res zero-tn t)      (inst b test)      (inst nor shift shift)      (emit-label loop)      (inst add res (fixnumize 1))      (emit-label test)      (inst bne shift loop)      (inst srl shift 1))))(define-vop (unsigned-byte-32-count)  (:translate logcount)  (:note "inline (unsigned-byte 32) logcount")  (:policy :fast-safe)  (:args (arg :scs (unsigned-reg) :target num))  (:arg-types unsigned-num)  (:results (res :scs (unsigned-reg)))  (:result-types positive-fixnum)  (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)                    :target res) num)  (:temporary (:scs (non-descriptor-reg)) mask temp)  (:generator 30    (inst li mask #x55555555)    (inst srl temp arg 1)    (inst and num arg mask)    (inst and temp mask)    (inst addu num temp)    (inst li mask #x33333333)    (inst srl temp num 2)    (inst and num mask)    (inst and temp mask)    (inst addu num temp)    (inst li mask #x0f0f0f0f)    (inst srl temp num 4)    (inst and num mask)    (inst and temp mask)    (inst addu num temp)    (inst li mask #x00ff00ff)    (inst srl temp num 8)    (inst and num mask)    (inst and temp mask)    (inst addu num temp)    (inst li mask #x0000ffff)    (inst srl temp num 16)    (inst and num mask)    (inst and temp mask)    (inst addu res num temp)));;; Multiply and Divide.(define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)  (:temporary (:scs (non-descriptor-reg)) temp)  (:translate *)  (:generator 4    (inst sra temp y n-fixnum-tag-bits)    (inst mult x temp)    (inst mflo r)))(define-vop (fast-*/signed=>signed fast-signed-binop)  (:translate *)  (:generator 3    (inst mult x y)    (inst mflo r)))(define-vop (fast-*/unsigned=>unsigned fast-unsigned-binop)  (:translate *)  (:generator 3    (inst multu x y)    (inst mflo r)))(define-vop (fast-truncate/fixnum fast-fixnum-binop)  (:translate truncate)  (:results (q :scs (any-reg))            (r :scs (any-reg)))  (:result-types tagged-num tagged-num)  (:temporary (:scs (non-descriptor-reg) :to :eval) temp)  (:vop-var vop)  (:save-p :compute-only)  (:generator 11    (let ((zero (generate-error-code vop division-by-zero-error x y)))      (inst beq y zero))    (inst nop)    (inst div x y)    (inst mflo temp)    (inst sll q temp n-fixnum-tag-bits)    (inst mfhi r)))(define-vop (fast-truncate/unsigned fast-unsigned-binop)  (:translate truncate)  (:results (q :scs (unsigned-reg))            (r :scs (unsigned-reg)))  (:result-types unsigned-num unsigned-num)  (:vop-var vop)  (:save-p :compute-only)  (:generator 12    (let ((zero (generate-error-code vop division-by-zero-error x y)))      (inst beq y zero))    (inst nop)    (inst divu x y)    (inst mflo q)    (inst mfhi r)))(define-vop (fast-truncate/signed fast-signed-binop)  (:translate truncate)  (:results (q :scs (signed-reg))            (r :scs (signed-reg)))  (:result-types signed-num signed-num)  (:vop-var vop)  (:save-p :compute-only)  (:generator 12    (let ((zero (generate-error-code vop division-by-zero-error x y)))      (inst beq y zero))    (inst nop)    (inst div x y)    (inst mflo q)    (inst mfhi r)));;;; Binary conditional VOPs:(define-vop (fast-conditional)  (:conditional)  (:info target not-p)  (:effects)  (:affected)  (:temporary (:scs (non-descriptor-reg)) temp)  (:policy :fast-safe))(define-vop (fast-conditional/fixnum fast-conditional)  (:args (x :scs (any-reg))         (y :scs (any-reg)))  (:arg-types tagged-num tagged-num)  (:note "inline fixnum comparison"))(define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg)))  (:arg-types tagged-num (:constant (signed-byte-with-a-bite-out 14 4)))  (:info target not-p y))(define-vop (fast-conditional/signed fast-conditional)  (:args (x :scs (signed-reg))         (y :scs (signed-reg)))  (:arg-types signed-num signed-num)  (:note "inline (signed-byte 32) comparison"))(define-vop (fast-conditional-c/signed fast-conditional/signed)  (:args (x :scs (signed-reg)))  (:arg-types signed-num (:constant (signed-byte-with-a-bite-out 16 1)))  (:info target not-p y))(define-vop (fast-conditional/unsigned fast-conditional)  (:args (x :scs (unsigned-reg))         (y :scs (unsigned-reg)))  (:arg-types unsigned-num unsigned-num)  (:note "inline (unsigned-byte 32) comparison"))(define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)  (:args (x :scs (unsigned-reg)))  (:arg-types unsigned-num (:constant (and (signed-byte-with-a-bite-out 16 1)                                           unsigned-byte)))  (:info target not-p y))(defmacro define-conditional-vop (translate &rest generator)  `(progn     ,@(mapcar #'(lambda (suffix cost signed)                   (unless (and (member suffix '(/fixnum -c/fixnum))                                (eq translate 'eql))                     `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"                                                    translate suffix))                                   ,(intern                                     (format nil "~:@(FAST-CONDITIONAL~A~)"                                             suffix)))                        (:translate ,translate)                        (:generator ,cost                          (let* ((signed ,signed)                                 (-c/fixnum ,(eq suffix '-c/fixnum))                                 (y (if -c/fixnum (fixnumize y) y)))                            (declare (ignorable signed -c/fixnum y))                            ,@generator)))))               '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)               '(3 2 5 4 5 4)               '(t t t t nil nil))))(define-conditional-vop <  (cond ((and signed (eql y 0))         (if not-p             (inst bgez x target)             (inst bltz x target)))        (t         (if signed             (inst slt temp x y)             (inst sltu temp x y))         (if not-p             (inst beq temp target)             (inst bne temp target))))  (inst nop))(define-conditional-vop >  (cond ((and signed (eql y 0))         (if not-p             (inst blez x target)             (inst bgtz x target)))        ((integerp y)         (let ((y (+ y (if -c/fixnum (fixnumize 1) 1))))           (if signed               (inst slt temp x y)               (inst sltu temp x y))           (if not-p               (inst bne temp target)               (inst beq temp target))))        (t         (if signed             (inst slt temp y x)             (inst sltu temp y x))         (if not-p             (inst beq temp target)             (inst bne temp target))))  (inst nop));;; EQL/FIXNUM is funny because the first arg can be of any type, not just a;;; known fixnum.(define-conditional-vop eql  (declare (ignore signed))  (when (integerp y)    (inst li temp y)    (setf y temp))  (if not-p      (inst bne x y target)      (inst beq x y target))  (inst nop));;; These versions specify a fixnum restriction on their first arg.  We have;;; also generic-eql/fixnum VOPs which are the same, but have no restriction on;;; the first arg and a higher cost.  The reason for doing this is to prevent;;; fixnum specific operations from being used on word integers, spuriously;;; consing the argument.;;;(define-vop (fast-eql/fixnum fast-conditional)  (:args (x :scs (any-reg))         (y :scs (any-reg)))  (:arg-types tagged-num tagged-num)  (:note "inline fixnum comparison")  (:translate eql)  (:ignore temp)  (:generator 3    (if not-p        (inst bne x y target)        (inst beq x y target))    (inst nop)));;;(define-vop (generic-eql/fixnum fast-eql/fixnum)  (:args (x :scs (any-reg descriptor-reg))         (y :scs (any-reg)))  (:arg-types * tagged-num)  (:variant-cost 7))(define-vop (fast-eql-c/fixnum fast-conditional/fixnum)  (:args (x :scs (any-reg)))  (:arg-types tagged-num (:constant (signed-byte 14)))  (:info target not-p y)  (:translate eql)  (:generator 2    (let ((y (cond ((eql y 0) zero-tn)                   (t                    (inst li temp (fixnumize y))                    temp))))      (if not-p          (inst bne x y target)          (inst beq x y target))      (inst nop))));;;(define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)  (:args (x :scs (any-reg descriptor-reg)))  (:arg-types * (:constant (signed-byte 14)))  (: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 beq shift done)      (inst srl res next shift)      (inst subu temp zero-tn shift)      (inst sll 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)

⌨️ 快捷键说明

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