;; at the low five bits of the result.
(inst sar result (min 31 (- amount)))
;; Fixnum correction.
- (inst and result #xfffffffc)))))))
+ (inst and result (lognot fixnum-tag-mask))))))))
(define-vop (fast-ash-left/fixnum=>fixnum)
(:translate ash)
(: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)
+ (:args (x :scs (signed-reg signed-stack))
+ (y :scs (signed-reg)))
+ (: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)
+ (:args (x :scs (unsigned-reg unsigned-stack))
+ (y :scs (unsigned-reg)))
+ (: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)