X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fppc%2Farith.lisp;h=67365c150f05b914c24d3624b68d35a53be1fadc;hb=4e6200853a661da5e73d0843a4afca9077a06fa8;hp=5a20c341a29a7a8215c2f9fc0e6cdc4415a951ba;hpb=6b2e5ac556aef4dbf54b60b9512edf1b9c5cc457;p=sbcl.git diff --git a/src/compiler/ppc/arith.lisp b/src/compiler/ppc/arith.lisp index 5a20c34..67365c1 100644 --- a/src/compiler/ppc/arith.lisp +++ b/src/compiler/ppc/arith.lisp @@ -661,6 +661,58 @@ (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-vop (lognot-mod32/unsigned=>unsigned) @@ -753,6 +805,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-