0.9.9.27:
[sbcl.git] / src / compiler / x86 / arith.lisp
index 46f5326..3910de9 100644 (file)
   (:arg-types unsigned-num (:constant (unsigned-byte 32)))
   (:info target not-p y))
 
+(macrolet ((define-logtest-vops ()
+             `(progn
+               ,@(loop for suffix in '(/fixnum -c/fixnum
+                                       /signed -c/signed
+                                       /unsigned -c/unsigned)
+                       for cost in '(4 3 6 5 6 5)
+                       collect
+                       `(define-vop (,(symbolicate "FAST-LOGTEST" suffix)
+                                     ,(symbolicate "FAST-CONDITIONAL" suffix))
+                         (:translate logtest)
+                         (:generator ,cost
+                          (inst test x ,(if (eq suffix '-c/fixnum)
+                                            '(fixnumize y)
+                                            'y))
+                          (inst jmp (if not-p :e :ne) target)))))))
+  (define-logtest-vops))
+
+(defknown %logbitp (integer unsigned-byte) boolean
+  (movable foldable flushable))
+
+(defun %logbitp (integer index)
+  (logbitp index integer))
+
+;;; too much work to do the non-constant case (maybe?)
+(define-vop (fast-logbitp-c/fixnum fast-conditional-c/fixnum)
+  (:translate %logbitp)
+  (:arg-types tagged-num (:constant (integer 0 29)))
+  (:generator 4
+    (inst bt x (+ y n-fixnum-tag-bits))
+    (inst jmp (if not-p :nc :c) target)))
+
+(define-vop (fast-logbitp/signed fast-conditional/signed)
+  (:translate %logbitp)
+  (:generator 6
+    (inst bt x y)
+    (inst jmp (if not-p :nc :c) target)))
+
+(define-vop (fast-logbitp-c/signed fast-conditional-c/signed)
+  (:translate %logbitp)
+  (:arg-types signed-num (:constant (integer 0 31)))
+  (:generator 5
+    (inst bt x y)
+    (inst jmp (if not-p :nc :c) target)))
+
+(define-vop (fast-logbitp/unsigned fast-conditional/unsigned)
+  (:translate %logbitp)
+  (:generator 6
+    (inst bt x y)
+    (inst jmp (if not-p :nc :c) target)))
+
+(define-vop (fast-logbitp-c/unsigned fast-conditional-c/unsigned)
+  (:translate %logbitp)
+  (:arg-types unsigned-num (:constant (integer 0 31)))
+  (:generator 5
+    (inst bt x y)
+    (inst jmp (if not-p :nc :c) target)))
 
 (macrolet ((define-conditional-vop (tran cond unsigned not-cond not-unsigned)
              `(progn
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
-;;; the it may be passed as a fixnum or word and thus may be 0, 1, or
+;;; that it may be passed as a fixnum or word and thus may be 0, 1, or
 ;;; 4. This is easy to deal with and may save a fixnum-word
 ;;; conversion.
 (define-vop (add-w/carry)
     (inst mov carry 0)
     (inst adc carry carry)))
 
-;;; Note: the borrow is the oppostite of the x86 convention - 1 for no
-;;; borrow and 0 for a borrow.
+;;; Note: the borrow is 1 for no borrow and 0 for a borrow, the opposite
+;;; of the x86 convention.
 (define-vop (sub-w/borrow)
   (:translate sb!bignum:%subtract-with-borrow)
   (:policy :fast-safe)
     (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 0)
-    (inst adc borrow borrow)
-    (inst xor borrow 1)))
+    (inst mov borrow 1)
+    (inst sbb borrow 0)))
 
 
 (define-vop (bignum-mult-and-add-3-arg)