Specialised VOPs for EQ of fixnum values on x86oids
[sbcl.git] / src / compiler / x86-64 / pred.lisp
index 8c9b2fd..11eab96 100644 (file)
                 (dolist (flag flags)
                   (inst cmov flag res then))))))))
 
-(macrolet ((def-move-if (name type reg &optional stack)
-               (when stack (setf stack (list stack)))
-
-               `(define-vop (,name move-if)
-                  (:args (then :scs (immediate ,reg ,@stack) :to :eval
-                               :load-if (not (or (sc-is then immediate)
-                                                 (and (sc-is then ,@stack)
-                                                      (not (location= else res))))))
-                         (else :scs (immediate ,reg ,@stack) :target res
-                               :load-if (not (sc-is else immediate ,@stack))))
-                  (:arg-types ,type ,type)
-                  (:results (res :scs (,reg)
-                                 :from (:argument 1)))
-                  (:result-types ,type))))
-  (def-move-if move-if/t
-      t descriptor-reg control-stack)
-  (def-move-if move-if/fx
-      tagged-num any-reg control-stack)
-  (def-move-if move-if/unsigned
-      unsigned-num unsigned-reg unsigned-stack)
-  (def-move-if move-if/signed
-      signed-num signed-reg signed-stack)
+(macrolet ((def-move-if (name type reg stack)
+             `(define-vop (,name move-if)
+                (:args (then :scs (immediate ,reg ,stack) :to :eval
+                             :load-if (not (or (sc-is then immediate)
+                                               (and (sc-is then ,stack)
+                                                    (not (location= else res))))))
+                       (else :scs (immediate ,reg ,stack) :target res
+                             :load-if (not (sc-is else immediate ,stack))))
+                (:arg-types ,type ,type)
+                (:results (res :scs (,reg)
+                               :from (:argument 1)))
+                (:result-types ,type))))
+  (def-move-if move-if/t t descriptor-reg control-stack)
+  (def-move-if move-if/fx tagged-num any-reg control-stack)
+  (def-move-if move-if/unsigned unsigned-num unsigned-reg unsigned-stack)
+  (def-move-if move-if/signed signed-num signed-reg signed-stack)
   ;; FIXME: See *CMOV-PTYPE-REPRESENTATION-VOP* above.
   #!+sb-unicode
-  (def-move-if move-if/char
-      character character-reg character-stack)
-  (def-move-if move-if/sap
-      system-area-pointer sap-reg sap-stack))
-
+  (def-move-if move-if/char character character-reg character-stack)
+  (def-move-if move-if/sap system-area-pointer sap-reg sap-stack))
 \f
 ;;;; conditional VOPs
 
   (:conditional :e)
   (:policy :fast-safe)
   (:translate eq)
-  (:generator 3
+  (:generator 8
     (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)
+             `(define-vop (,eq-name ,eql-name)
+                (:translate eq))))
+  (def fast-if-eq-character fast-char=/character)
+  (def fast-if-eq-character/c fast-char=/character/c)
+  (def fast-if-eq-fixnum fast-eql/fixnum)
+  (def fast-if-eq-fixnum/x fast-eql-c/fixnum)
+  (def fast-if-eq/signed fast-if-eql/signed)
+  (def fast-if-eq-c/signed fast-if-eql-c/signed)
+  (def fast-if-eq/unsigned fast-if-eql/unsigned)
+  (def fast-if-eq-c/unsigned fast-if-eql-c/unsigned))