X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fppc%2Farith.lisp;h=f8cb9aa1b44dce12979bf203c4cd2f3cb26bc6af;hb=7deecae2d959173eda6a153d490c752c32050a9e;hp=916ed0f7e07ae07045cdb5088656371d2d551287;hpb=40859b35c1bff1d7d8773bbcda7b25bca4e553e3;p=sbcl.git diff --git a/src/compiler/ppc/arith.lisp b/src/compiler/ppc/arith.lisp index 916ed0f..f8cb9aa 100644 --- a/src/compiler/ppc/arith.lisp +++ b/src/compiler/ppc/arith.lisp @@ -44,12 +44,12 @@ (define-vop (fast-lognot/fixnum fixnum-unop) (:translate lognot) - (:generator 2 - (inst xori res x (fixnumize -1)))) + (:generator 1 + (inst subfic res x (fixnumize -1)))) (define-vop (fast-lognot/signed signed-unop) (:translate lognot) - (:generator 1 + (:generator 2 (inst not res x))) ;;;; Binary fixnum operations. @@ -58,7 +58,7 @@ (define-vop (fast-fixnum-binop fast-safe-arith-op) (:args (x :target r :scs (any-reg zero)) - (y :target r :scs (any-reg zero))) + (y :target r :scs (any-reg zero))) (:arg-types tagged-num tagged-num) (:results (r :scs (any-reg))) (:result-types tagged-num) @@ -66,7 +66,7 @@ (define-vop (fast-unsigned-binop fast-safe-arith-op) (:args (x :target r :scs (unsigned-reg zero)) - (y :target r :scs (unsigned-reg zero))) + (y :target r :scs (unsigned-reg zero))) (:arg-types unsigned-num unsigned-num) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) @@ -74,7 +74,7 @@ (define-vop (fast-signed-binop fast-safe-arith-op) (:args (x :target r :scs (signed-reg zero)) - (y :target r :scs (signed-reg zero))) + (y :target r :scs (signed-reg zero))) (:arg-types signed-num signed-num) (:results (r :scs (signed-reg))) (:result-types signed-num) @@ -84,7 +84,7 @@ (:args (x :target r :scs (any-reg zero))) (:info y) (:arg-types tagged-num - (:constant (and (signed-byte 14) (not (integer 0 0))))) + (:constant (and (signed-byte 14) (not (integer 0 0))))) (:results (r :scs (any-reg))) (:result-types tagged-num) (:note "inline fixnum arithmetic")) @@ -93,7 +93,7 @@ (:args (x :target r :scs (any-reg zero))) (:info y) (:arg-types tagged-num - (:constant (and (signed-byte 30) (not (integer 0 0))))) + (:constant (and (signed-byte 30) (not (integer 0 0))))) (:results (r :scs (any-reg))) (:result-types tagged-num) (:note "inline fixnum arithmetic")) @@ -102,7 +102,7 @@ (:args (x :target r :scs (any-reg zero))) (:info y) (:arg-types tagged-num - (:constant (and (unsigned-byte 14) (not (integer 0 0))))) + (:constant (and (unsigned-byte 14) (not (integer 0 0))))) (:results (r :scs (any-reg))) (:result-types tagged-num) (:note "inline fixnum logical op")) @@ -111,7 +111,7 @@ (:args (x :target r :scs (any-reg zero))) (:info y) (:arg-types tagged-num - (:constant (and (unsigned-byte 16) (not (integer 0 0))))) + (:constant (and (unsigned-byte 16) (not (integer 0 0))))) (:results (r :scs (any-reg))) (:result-types tagged-num) (:note "inline fixnum logical op")) @@ -120,7 +120,7 @@ (:args (x :target r :scs (unsigned-reg zero))) (:info y) (:arg-types unsigned-num - (:constant (and (signed-byte 16) (not (integer 0 0))))) + (:constant (and (signed-byte 16) (not (integer 0 0))))) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:note "inline (unsigned-byte 32) arithmetic")) @@ -129,7 +129,7 @@ (:args (x :target r :scs (unsigned-reg zero))) (:info y) (:arg-types unsigned-num - (:constant (and (unsigned-byte 32) (not (integer 0 0))))) + (:constant (and (unsigned-byte 32) (not (integer 0 0))))) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:note "inline (unsigned-byte 32) arithmetic")) @@ -138,7 +138,7 @@ (:args (x :target r :scs (signed-reg zero))) (:info y) (:arg-types signed-num - (:constant (and (signed-byte 32) (not (integer 0 0))))) + (:constant (and (signed-byte 32) (not (integer 0 0))))) (:results (r :scs (signed-reg))) (:result-types signed-num) (:note "inline (signed-byte 32) arithmetic")) @@ -147,7 +147,7 @@ (:args (x :target r :scs (unsigned-reg zero))) (:info y) (:arg-types unsigned-num - (:constant (and (unsigned-byte 16) (not (integer 0 0))))) + (:constant (and (unsigned-byte 16) (not (integer 0 0))))) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:note "inline (unsigned-byte 32) logical op")) @@ -156,7 +156,7 @@ (:args (x :target r :scs (unsigned-reg zero))) (:info y) (:arg-types unsigned-num - (:constant (and (unsigned-byte 32) (not (integer 0 0))))) + (:constant (and (unsigned-byte 32) (not (integer 0 0))))) (:results (r :scs (unsigned-reg))) (:result-types unsigned-num) (:note "inline (unsigned-byte 32) logical op")) @@ -165,7 +165,7 @@ (:args (x :target r :scs (signed-reg zero))) (:info y) (:arg-types signed-num - (:constant (and (unsigned-byte 32) (not (integer 0 0))))) + (:constant (and (unsigned-byte 32) (not (integer 0 0))))) (:results (r :scs (signed-reg))) (:result-types signed-num) (:note "inline (signed-byte 32) logical op")) @@ -174,7 +174,7 @@ (:args (x :target r :scs (signed-reg zero))) (:info y) (:arg-types signed-num - (:constant (and (signed-byte 16) (not (integer 0 0))))) + (:constant (and (signed-byte 16) (not (integer 0 0))))) (:results (r :scs (signed-reg))) (:result-types signed-num) (:note "inline (signed-byte 32) arithmetic")) @@ -183,43 +183,43 @@ (:args (x :target r :scs (signed-reg zero))) (:info y) (:arg-types signed-num - (:constant (and (unsigned-byte 16) (not (integer 0 0))))) + (:constant (and (unsigned-byte 16) (not (integer 0 0))))) (:results (r :scs (signed-reg))) (:result-types signed-num) (:note "inline (signed-byte 32) logical op")) (eval-when (:compile-toplevel :load-toplevel :execute) -(defmacro !define-var-binop (translate untagged-penalty op +(defmacro !define-var-binop (translate untagged-penalty op &optional arg-swap restore-fixnum-mask) `(progn (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM") - fast-fixnum-binop) + fast-fixnum-binop) ,@(when restore-fixnum-mask - `((:temporary (:sc non-descriptor-reg) temp))) + `((:temporary (:sc non-descriptor-reg) temp))) (:translate ,translate) (:generator 2 - ,(if arg-swap - `(inst ,op ,(if restore-fixnum-mask 'temp 'r) y x) - `(inst ,op ,(if restore-fixnum-mask 'temp 'r) x y)) - ;; FIXME: remind me what convention we used for 64bitizing - ;; stuff? -- CSR, 2003-08-27 - ,@(when restore-fixnum-mask - `((inst clrrwi r temp (1- n-lowtag-bits)))))) + ,(if arg-swap + `(inst ,op ,(if restore-fixnum-mask 'temp 'r) y x) + `(inst ,op ,(if restore-fixnum-mask 'temp 'r) x y)) + ;; FIXME: remind me what convention we used for 64bitizing + ;; stuff? -- CSR, 2003-08-27 + ,@(when restore-fixnum-mask + `((inst clrrwi r temp (1- n-lowtag-bits)))))) (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED") - fast-signed-binop) + fast-signed-binop) (:translate ,translate) (:generator ,(1+ untagged-penalty) ,(if arg-swap - `(inst ,op r y x) - `(inst ,op r x y)))) + `(inst ,op r y x) + `(inst ,op r x y)))) (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED") - fast-unsigned-binop) + fast-unsigned-binop) (:translate ,translate) (:generator ,(1+ untagged-penalty) - ,(if arg-swap - `(inst ,op r y x) - `(inst ,op r x y)))))) + ,(if arg-swap + `(inst ,op r y x) + `(inst ,op r x y)))))) ;;; FIXME: the code has really only been checked for adds; we could do ;;; subtracts, too, but my brain is not up to the task of figuring out @@ -227,7 +227,7 @@ (defmacro !define-const-binop (translate untagged-penalty op &optional (shifted-op nil)) `(progn (define-vop (,(symbolicate 'fast- translate '-c/fixnum=>fixnum) - ,(if shifted-op + ,(if shifted-op 'fast-fixnum-binop30-c 'fast-fixnum-binop-c)) (:translate ,translate) @@ -264,7 +264,7 @@ (inst ,op r temp low-half))))) `(inst ,op r x (fixnumize y))))) (define-vop (,(symbolicate 'fast- translate '-c/signed=>signed) - ,(if shifted-op + ,(if shifted-op 'fast-signed-binop32-c 'fast-signed-binop-c)) (:translate ,translate) @@ -300,7 +300,7 @@ (inst ,op r temp low-half))))) `(inst ,op r x y)))) (define-vop (,(symbolicate 'fast- translate '-c/unsigned=>unsigned) - ,(if shifted-op + ,(if shifted-op 'fast-unsigned-binop32-c 'fast-unsigned-binop-c)) (:translate ,translate) @@ -341,7 +341,7 @@ (defmacro !define-const-logop (translate untagged-penalty op &optional (shifted-op nil)) `(progn (define-vop (,(symbolicate 'fast- translate '-c/fixnum=>fixnum) - ,(if shifted-op + ,(if shifted-op 'fast-fixnum-logop30-c 'fast-fixnum-logop-c)) (:translate ,translate) @@ -360,14 +360,14 @@ (inst ,op r temp low-half)))) `(inst ,op r x (fixnumize y))))) (define-vop (,(symbolicate 'fast- translate '-c/signed=>signed) - ,(if shifted-op + ,(if shifted-op 'fast-signed-logop32-c 'fast-signed-logop-c)) (:translate ,translate) ,@(when shifted-op `((:temporary (:sc non-descriptor-reg :target r) temp))) (:generator ,untagged-penalty - ,(if shifted-op + ,(if shifted-op `(let ((high-half (ldb (byte 16 16) y)) (low-half (ldb (byte 16 0) y))) (cond @@ -378,7 +378,7 @@ (inst ,op r temp low-half)))) `(inst ,op r x y)))) (define-vop (,(symbolicate 'fast- translate '-c/unsigned=>unsigned) - ,(if shifted-op + ,(if shifted-op 'fast-unsigned-logop32-c 'fast-unsigned-logop-c)) (:translate ,translate) @@ -438,7 +438,7 @@ (inst addo. r x y) (inst bns no-overflow) (inst unimp (logior (ash (reg-tn-encoding r) 5) - fixnum-additive-overflow-trap)) + fixnum-additive-overflow-trap)) (emit-label no-overflow)))) (define-vop (-/fixnum fast--/fixnum=>fixnum) @@ -452,27 +452,27 @@ (inst subo. r x y) (inst bns no-overflow) (inst unimp (logior (ash (reg-tn-encoding r) 5) - fixnum-additive-overflow-trap)) + fixnum-additive-overflow-trap)) (emit-label no-overflow)))) (define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop) (:temporary (:scs (non-descriptor-reg)) temp) (:translate *) (:generator 2 - (inst srawi temp y 2) + (inst srawi temp y n-fixnum-tag-bits) (inst mullw r x temp))) (define-vop (fast-*-c/fixnum=>fixnum fast-fixnum-binop-c) (:translate *) - (:arg-types tagged-num - (:constant (and (signed-byte 16) (not (integer 0 0))))) + (:arg-types tagged-num + (:constant (and (signed-byte 16) (not (integer 0 0))))) (:generator 1 (inst mulli r x y))) (define-vop (fast-*-bigc/fixnum=>fixnum fast-fixnum-binop-c) (:translate *) (:arg-types tagged-num - (:constant (and fixnum (not (signed-byte 16))))) + (:constant (and fixnum (not (signed-byte 16))))) (:temporary (:scs (non-descriptor-reg)) temp) (:generator 1 (inst lr temp y) @@ -501,23 +501,23 @@ ;;; Shifting (macrolet ((def (name sc-type type result-type cost) - `(define-vop (,name) - (:note "inline ASH") - (:translate ash) - (:args (number :scs (,sc-type)) - (amount :scs (signed-reg unsigned-reg immediate))) - (:arg-types ,type positive-fixnum) - (:results (result :scs (,result-type))) - (:result-types ,type) - (:policy :fast-safe) - (:generator ,cost - (sc-case amount - ((signed-reg unsigned-reg) - (inst slw result number amount)) - (immediate - (let ((amount (tn-value amount))) - (aver (> amount 0)) - (inst slwi result number amount)))))))) + `(define-vop (,name) + (:note "inline ASH") + (:translate ash) + (:args (number :scs (,sc-type)) + (amount :scs (signed-reg unsigned-reg immediate))) + (:arg-types ,type positive-fixnum) + (:results (result :scs (,result-type))) + (:result-types ,type) + (:policy :fast-safe) + (:generator ,cost + (sc-case amount + ((signed-reg unsigned-reg) + (inst slw result number amount)) + (immediate + (let ((amount (tn-value amount))) + (aver (> amount 0)) + (inst slwi result number amount)))))))) ;; FIXME: There's the opportunity for a sneaky optimization here, I ;; think: a FAST-ASH-LEFT-C/FIXNUM=>SIGNED vop. -- CSR, 2003-09-03 (def fast-ash-left/fixnum=>fixnum any-reg tagged-num any-reg 2) @@ -527,7 +527,7 @@ (define-vop (fast-ash/unsigned=>unsigned) (:note "inline ASH") (:args (number :scs (unsigned-reg) :to :save) - (amount :scs (signed-reg))) + (amount :scs (signed-reg))) (:arg-types (:or unsigned-num) signed-num) (:results (result :scs (unsigned-reg))) (:result-types unsigned-num) @@ -536,7 +536,7 @@ (:temporary (:sc non-descriptor-reg) ndesc) (:generator 5 (let ((positive (gen-label)) - (done (gen-label))) + (done (gen-label))) (inst cmpwi amount 0) (inst neg ndesc amount) (inst bge positive) @@ -545,11 +545,11 @@ (inst ble done) (move result zero-tn) (inst b done) - + (emit-label positive) ;; The result-type assures us that this shift will not overflow. (inst slw result number amount) - + (emit-label done)))) (define-vop (fast-ash-c/unsigned=>unsigned) @@ -572,7 +572,7 @@ (define-vop (fast-ash/signed=>signed) (:note "inline ASH") (:args (number :scs (signed-reg) :to :save) - (amount :scs (signed-reg immediate))) + (amount :scs (signed-reg immediate))) (:arg-types (:or signed-num) signed-num) (:results (result :scs (signed-reg))) (:result-types (:or signed-num)) @@ -583,30 +583,28 @@ (sc-case amount (signed-reg (let ((positive (gen-label)) - (done (gen-label))) - (inst cmpwi amount 0) - (inst neg ndesc amount) - (inst bge positive) - (inst cmpwi ndesc 31) - (inst sraw result number ndesc) - (inst ble done) - (inst srawi result number 31) - (inst b done) - - (emit-label positive) - ;; The result-type assures us that this shift will not overflow. - (inst slw result number amount) - - (emit-label done))) + (done (gen-label))) + (inst cmpwi amount 0) + (inst neg ndesc amount) + (inst bge positive) + (inst cmpwi ndesc 31) + (inst sraw result number ndesc) + (inst ble done) + (inst srawi result number 31) + (inst b done) + + (emit-label positive) + ;; The result-type assures us that this shift will not overflow. + (inst slw result number amount) + + (emit-label done))) (immediate (let ((amount (tn-value amount))) - (if (minusp amount) - (let ((amount (min 31 (- amount)))) - (inst srawi result number amount)) - (inst slwi result number amount))))))) - - + (if (minusp amount) + (let ((amount (min 31 (- amount)))) + (inst srawi result number amount)) + (inst slwi result number amount))))))) (define-vop (signed-byte-32-len) (:translate integer-length) @@ -614,19 +612,29 @@ (:policy :fast-safe) (:args (arg :scs (signed-reg))) (:arg-types signed-num) - (:results (res :scs (any-reg))) - (:result-types positive-fixnum) - (:temporary (:scs (non-descriptor-reg) :to (:argument 0)) shift) + (:results (res :scs (unsigned-reg) :from :load)) + (:result-types unsigned-num) (:generator 6 ; (integer-length arg) = (- 32 (cntlz (if (>= arg 0) arg (lognot arg)))) (let ((nonneg (gen-label))) - (inst cntlzw. shift arg) + (inst cntlzw. res arg) (inst bne nonneg) - (inst not shift arg) - (inst cntlzw shift shift) + (inst not res arg) + (inst cntlzw res res) (emit-label nonneg) - (inst slwi shift shift 2) - (inst subfic res shift (fixnumize 32))))) + (inst subfic res res 32)))) + +(define-vop (unsigned-byte-32-len) + (:translate integer-length) + (:note "inline (unsigned-byte 32) integer-length") + (:policy :fast-safe) + (:args (arg :scs (unsigned-reg))) + (:arg-types unsigned-num) + (:results (res :scs (unsigned-reg))) + (:result-types unsigned-num) + (:generator 4 + (inst cntlzw res arg) + (inst subfic res res 32))) (define-vop (unsigned-byte-32-count) (:translate logcount) @@ -639,7 +647,7 @@ (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift temp) (:generator 30 (let ((loop (gen-label)) - (done (gen-label))) + (done (gen-label))) (inst add. shift zero-tn arg) (move res zero-tn) (inst beq done) @@ -653,8 +661,60 @@ (emit-label done)))) +;;;; %LDB + +(defknown %%ldb (integer unsigned-byte unsigned-byte) unsigned-byte + (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 :unsigned 32) +(define-modular-fun lognot-mod32 (x) lognot :untagged nil 32) (define-vop (lognot-mod32/unsigned=>unsigned) (:translate lognot-mod32) (:args (x :scs (unsigned-reg))) @@ -666,35 +726,34 @@ (inst not res x))) (define-vop (fast-ash-left-mod32-c/unsigned=>unsigned - fast-ash-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))) + ((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 +(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 :unsigned 32) - (define-vop (,modvop ,vop) - (:translate ,mfun-name)) - ,@(when constantp - `((define-vop (,modcvop ,cvop) - (:translate ,mfun-name)))))))) + (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 logxor t) (define-modular-backend logeqv) (define-modular-backend lognand) (define-modular-backend lognor) @@ -714,7 +773,7 @@ (define-vop (fast-conditional/fixnum fast-conditional) (:args (x :scs (any-reg zero)) - (y :scs (any-reg zero))) + (y :scs (any-reg zero))) (:arg-types tagged-num tagged-num) (:note "inline fixnum comparison")) @@ -725,7 +784,7 @@ (define-vop (fast-conditional/signed fast-conditional) (:args (x :scs (signed-reg zero)) - (y :scs (signed-reg zero))) + (y :scs (signed-reg zero))) (:arg-types signed-num signed-num) (:note "inline (signed-byte 32) comparison")) @@ -736,7 +795,7 @@ (define-vop (fast-conditional/unsigned fast-conditional) (:args (x :scs (unsigned-reg zero)) - (y :scs (unsigned-reg zero))) + (y :scs (unsigned-reg zero))) (:arg-types unsigned-num unsigned-num) (:note "inline (unsigned-byte 32) comparison")) @@ -745,6 +804,71 @@ (: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- (+ adds shifts) 4) - (give-up-ir1-transform))) + ;; a mulli instruction has a latency of 5. + (when (> (+ adds shifts) 4) + (give-up-ir1-transform))) (t - ;; a mullw instruction also has a latency of 5, plus two - ;; instructions (in general) to load the immediate into a - ;; register. - (when (> (+ adds shifts) 6) - (give-up-ir1-transform)))) + ;; a mullw instruction also has a latency of 5, plus two + ;; instructions (in general) to load the immediate into a + ;; register. + (when (> (+ adds shifts) 6) + (give-up-ir1-transform)))) (or result 0))))