;; was true.
(return))
(t
- (unless (= start bignum-widetag)
- (inst cmp al-tn start)
- (if (= end complex-array-widetag)
- (progn
- (aver last)
- (inst jmp greater-or-equal target))
- (inst jmp :b when-false))) ; was :l
- (unless (= end complex-array-widetag)
- (inst cmp al-tn end)
- (if last
- (inst jmp less-or-equal target)
- (inst jmp :be when-true)))))))))))) ; was :le
+ (cond
+ ((= start bignum-widetag)
+ (inst cmp al-tn end)
+ (if last
+ (inst jmp less-or-equal target)
+ (inst jmp :be when-true)))
+ ((= end complex-array-widetag)
+ (inst cmp al-tn start)
+ (if last
+ (inst jmp greater-or-equal target)
+ (inst jmp :b when-false)))
+ ((not last)
+ (inst cmp al-tn start)
+ (inst jmp :b when-false)
+ (inst cmp al-tn end)
+ (if last
+ (inst jmp less-or-equal target)
+ (inst jmp :be when-true)))
+ (t
+ (inst sub al-tn start)
+ (inst cmp al-tn (- end start))
+ (inst jmp less-or-equal target))))))))))))
(emit-label drop-through))))
\f
;;;; type checking and testing
(:arg-types unsigned-num)
(:translate fixnump)
(:generator 5
+ ;; We could encode this with :Z and SHR, analogously to the signed-byte-32
+ ;; case below -- as we do on x86-64 -- but that costs us an extra
+ ;; register. Compromises...
(inst cmp value #.sb!xc:most-positive-fixnum)))
+(define-vop (fixnump/signed-byte-32 type-predicate)
+ (:args (value :scs (signed-reg)))
+ (:info)
+ (:conditional :z)
+ (:arg-types signed-num)
+ (:translate fixnump)
+ (:generator 5
+ ;; Hackers Delight, p. 53: signed
+ ;; a <= x <= a + 2^n - 1
+ ;; is equivalent to unsigned
+ ;; ((x-a) >> n) = 0
+ (inst mov eax-tn value)
+ (inst sub eax-tn #.sb!xc:most-negative-fixnum)
+ (inst shr eax-tn #.(integer-length (- sb!xc:most-positive-fixnum
+ sb!xc:most-negative-fixnum)))))
+
;;; A (SIGNED-BYTE 32) can be represented with either fixnum or a bignum with
;;; exactly one digit.