📄 arith.lisp
字号:
(movable foldable flushable always-translatable));;; only for constant folding within the compiler(defun %%ldb (integer size posn) (sb!kernel::%ldb size posn integer))(define-vop (ldb-c/fixnum) (:translate %%ldb) (:args (x :scs (any-reg))) (:arg-types tagged-num (:constant (integer 1 29)) (:constant (integer 0 29))) (:info size posn) (:results (res :scs (any-reg))) (:result-types tagged-num) (:policy :fast-safe) (:generator 2 (inst rlwinm res x (mod (- 32 posn) 32) ; effectively rotate right (- 32 size n-fixnum-tag-bits) (- 31 n-fixnum-tag-bits))))(define-vop (ldb-c/signed) (:translate %%ldb) (:args (x :scs (signed-reg))) (:arg-types signed-num (:constant (integer 1 29)) (:constant (integer 0 29))) (:info size posn) (:results (res :scs (any-reg))) (:result-types tagged-num) (:policy :fast-safe) (:generator 3 (inst rlwinm res x (mod (- (+ 32 n-fixnum-tag-bits) posn) 32) (- 32 size n-fixnum-tag-bits) (- 31 n-fixnum-tag-bits))))(define-vop (ldb-c/unsigned) (:translate %%ldb) (:args (x :scs (unsigned-reg))) (:arg-types unsigned-num (:constant (integer 1 29)) (:constant (integer 0 29))) (:info size posn) (:results (res :scs (any-reg))) (:result-types tagged-num) (:policy :fast-safe) (:generator 3 (inst rlwinm res x (mod (- (+ 32 n-fixnum-tag-bits) posn) 32) (- 32 size n-fixnum-tag-bits) (- 31 n-fixnum-tag-bits))));;;; Modular functions:(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 (res :scs (unsigned-reg))) (:result-types unsigned-num) (:policy :fast-safe) (:generator 1 (inst not res x)))(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))(macrolet ((define-modular-backend (fun &optional constantp) (let ((mfun-name (symbolicate fun '-mod32)) (modvop (symbolicate 'fast- fun '-mod32/unsigned=>unsigned)) (modcvop (symbolicate 'fast- fun 'mod32-c/unsigned=>unsigned)) (vop (symbolicate 'fast- fun '/unsigned=>unsigned)) (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned))) `(progn (define-modular-fun ,mfun-name (x y) ,fun :untagged nil 32) (define-vop (,modvop ,vop) (:translate ,mfun-name)) ,@(when constantp `((define-vop (,modcvop ,cvop) (:translate ,mfun-name)))))))) (define-modular-backend + t) (define-modular-backend - t) (define-modular-backend * t) (define-modular-backend logeqv) (define-modular-backend lognand) (define-modular-backend lognor) (define-modular-backend logandc1) (define-modular-backend logandc2) (define-modular-backend logorc1) (define-modular-backend logorc2));;;; Binary conditional VOPs:(define-vop (fast-conditional) (:conditional) (:info target not-p) (:effects) (:affected) (:policy :fast-safe))(define-vop (fast-conditional/fixnum fast-conditional) (:args (x :scs (any-reg zero)) (y :scs (any-reg zero))) (:arg-types tagged-num tagged-num) (:note "inline fixnum comparison"))(define-vop (fast-conditional-c/fixnum fast-conditional/fixnum) (:args (x :scs (any-reg zero))) (:arg-types tagged-num (:constant (signed-byte 14))) (:info target not-p y))(define-vop (fast-conditional/signed fast-conditional) (:args (x :scs (signed-reg zero)) (y :scs (signed-reg zero))) (: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 zero))) (:arg-types signed-num (:constant (signed-byte 16))) (:info target not-p y))(define-vop (fast-conditional/unsigned fast-conditional) (:args (x :scs (unsigned-reg zero)) (y :scs (unsigned-reg zero))) (: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 zero))) (:arg-types unsigned-num (:constant (unsigned-byte 16))) (:info target not-p y))(macrolet ((define-logtest-vops () `(progn ,@(loop for suffix in '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned) for sc in '(any-reg any-reg signed-reg signed-reg unsigned-reg unsigned-reg) for cost in '(4 3 6 5 6 5) collect `(define-vop (,(symbolicate "FAST-LOGTEST" suffix) ,(symbolicate "FAST-CONDITIONAL" suffix)) (:translate logtest) (:temporary (:scs (,sc) :to (:result 0)) test) (:generator ,cost ;; We could be a lot more sophisticated here and ;; check for possibilities with ANDIS.. ,(if (string= "-C" suffix :end2 2) `(inst andi. test x ,(if (eq suffix '-c/fixnum) '(fixnumize y) 'y)) `(inst and. test x y)) (inst b? (if not-p :eq :ne) target))))))) (define-logtest-vops))(defknown %logbitp (integer unsigned-byte) boolean (movable foldable flushable always-translatable));;; only for constant folding within the compiler(defun %logbitp (integer index) (logbitp index integer));;; We only handle the constant cases because those are the only ones;;; guaranteed to make it past COMBINATION-IMPLEMENTATION-STYLE.;;; --njf, 06-02-2006(define-vop (fast-logbitp-c/fixnum fast-conditional-c/fixnum) (:translate %logbitp) (:arg-types tagged-num (:constant (integer 0 29))) (:temporary (:scs (any-reg) :to (:result 0)) test) (:generator 4 (if (< y 14) (inst andi. test x (ash 1 (+ y n-fixnum-tag-bits))) (inst andis. test x (ash 1 (- y 14)))) (inst b? (if not-p :eq :ne) target)))(define-vop (fast-logbitp-c/signed fast-conditional-c/signed) (:translate %logbitp) (:arg-types signed-num (:constant (integer 0 31))) (:temporary (:scs (signed-reg) :to (:result 0)) test) (:generator 4 (if (< y 16) (inst andi. test x (ash 1 y)) (inst andis. test x (ash 1 (- y 16)))) (inst b? (if not-p :eq :ne) target)))(define-vop (fast-logbitp-c/unsigned fast-conditional-c/unsigned) (:translate %logbitp) (:arg-types unsigned-num (:constant (integer 0 31))) (:temporary (:scs (unsigned-reg) :to (:result 0)) test) (:generator 4 (if (< y 16) (inst andi. test x (ash 1 y)) (inst andis. test x (ash 1 (- y 16)))) (inst b? (if not-p :eq :ne) target)))(define-vop (fast-if-</fixnum fast-conditional/fixnum) (:translate <) (:generator 4 (inst cmpw x y) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if-<-c/fixnum fast-conditional-c/fixnum) (:translate <) (:generator 3 (inst cmpwi x (fixnumize y)) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if-</signed fast-conditional/signed) (:translate <) (:generator 6 (inst cmpw x y) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if-<-c/signed fast-conditional-c/signed) (:translate <) (:generator 5 (inst cmpwi x y) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if-</unsigned fast-conditional/unsigned) (:translate <) (:generator 6 (inst cmplw x y) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if-<-c/unsigned fast-conditional-c/unsigned) (:translate <) (:generator 5 (inst cmplwi x y) (inst b? (if not-p :ge :lt) target)))(define-vop (fast-if->/fixnum fast-conditional/fixnum) (:translate >) (:generator 4 (inst cmpw x y) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if->-c/fixnum fast-conditional-c/fixnum) (:translate >) (:generator 3 (inst cmpwi x (fixnumize y)) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if->/signed fast-conditional/signed) (:translate >) (:generator 6 (inst cmpw x y) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if->-c/signed fast-conditional-c/signed) (:translate >) (:generator 5 (inst cmpwi x y) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if->/unsigned fast-conditional/unsigned) (:translate >) (:generator 6 (inst cmplw x y) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if->-c/unsigned fast-conditional-c/unsigned) (:translate >) (:generator 5 (inst cmplwi x y) (inst b? (if not-p :le :gt) target)))(define-vop (fast-if-eql/signed fast-conditional/signed) (:translate eql) (:generator 6 (inst cmpw x y) (inst b? (if not-p :ne :eq) target)))(define-vop (fast-if-eql-c/signed fast-conditional-c/signed) (:translate eql) (:generator 5 (inst cmpwi x y) (inst b? (if not-p :ne :eq) target)))(define-vop (fast-if-eql/unsigned fast-conditional/unsigned) (:translate eql) (:generator 6 (inst cmplw x y) (inst b? (if not-p :ne :eq) target)))(define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned) (:translate eql) (:generator 5 (inst cmplwi x y) (inst b? (if not-p :ne :eq) target)));;; EQL/FIXNUM is funny because the first arg can be of any type, not just a;;; known fixnum.;;; 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 descriptor-reg zero)) (y :scs (any-reg zero))) (:arg-types tagged-num tagged-num) (:note "inline fixnum comparison") (:translate eql) (:generator 4 (inst cmpw x y) (inst b? (if not-p :ne :eq) target)));;;(define-vop (generic-eql/fixnum fast-eql/fixnum) (:arg-types * tagged-num) (:variant-cost 7))(define-vop (fast-eql-c/fixnum fast-conditional/fixnum) (:args (x :scs (any-reg descriptor-reg zero))) (:arg-types tagged-num (:constant (signed-byte 14))) (:info target not-p y) (:translate eql) (:generator 2 (inst cmpwi x (fixnumize y))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -