X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fpred.lisp;h=11eab96a3be8443abe6b3c1f70f776b084791a81;hb=2372ff8da6e1099e8840b0815d75c414fff2f302;hp=428c2c1de0135a47a61bb4b88418e62b5ee9cdab;hpb=47f408ca8480937ac946db8455b7c3d3e0b353bb;p=sbcl.git diff --git a/src/compiler/x86-64/pred.lisp b/src/compiler/x86-64/pred.lisp index 428c2c1..11eab96 100644 --- a/src/compiler/x86-64/pred.lisp +++ b/src/compiler/x86-64/pred.lisp @@ -217,7 +217,7 @@ (:conditional :e) (:policy :fast-safe) (:translate eq) - (:generator 3 + (:generator 8 (cond ((sc-is y immediate) (let ((val (tn-value y))) @@ -258,3 +258,23 @@ 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))