the values, and VOP-name the name of the VOP that will be used
to execute the conditional move.")
-(!def-vm-support-routine
+(defun
convert-conditional-move-p (node dst-tn x-tn y-tn)
(declare (ignore node))
(let* ((ptype (sb!c::tn-primitive-type dst-tn))
(:conditional :e)
(:policy :fast-safe)
(:translate eq)
- (:generator 3
+ (:generator 6
(cond
((sc-is y immediate)
(let ((val (tn-value y)))
character-widetag))))))
(t
(inst cmp x y)))))
+
+;; The template above is a very good fallback for the generic
+;; case. However, it is sometimes possible to perform unboxed
+;; comparisons. Repurpose char= and eql templates here, instead
+;; of forcing values to be boxed and then compared.
+;;
+;; We only weaken EQL => EQ for characters and fixnums, and detect
+;; when types definitely mismatch. No need to import other EQL
+;; VOPs (e.g. floats).
+(macrolet ((def (eq-name eql-name cost)
+ `(define-vop (,eq-name ,eql-name)
+ (:translate eq)
+ (:variant-cost ,cost))))
+ (def fast-if-eq-character fast-char=/character 3)
+ (def fast-if-eq-character/c fast-char=/character/c 2)
+ (def fast-if-eq-fixnum fast-eql/fixnum 3)
+ (def fast-if-eq-fixnum/c fast-eql-c/fixnum 2)
+ (def fast-if-eq-signed fast-if-eql/signed 5)
+ (def fast-if-eq-signed/c fast-if-eql-c/signed 4)
+ (def fast-if-eq-unsigned fast-if-eql/unsigned 5)
+ (def fast-if-eq-unsigned/c fast-if-eql-c/unsigned 4))