X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fpred.lisp;h=8f2abbd8d21c0fc572d24fdc40fed86cf141033b;hb=74cf7a4d01664fbf72a662ba093ad67ca243b524;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..8f2abbd 100644 --- a/src/compiler/x86-64/pred.lisp +++ b/src/compiler/x86-64/pred.lisp @@ -95,8 +95,7 @@ the values, and VOP-name the name of the VOP that will be used to execute the conditional move.") -(!def-vm-support-routine - convert-conditional-move-p (node dst-tn x-tn y-tn) +(defun convert-conditional-move-p (node dst-tn x-tn y-tn) (declare (ignore node)) (let* ((ptype (sb!c::tn-primitive-type dst-tn)) (name (sb!c::primitive-type-name ptype)) @@ -217,7 +216,7 @@ (:conditional :e) (:policy :fast-safe) (:translate eq) - (:generator 3 + (:generator 6 (cond ((sc-is y immediate) (let ((val (tn-value y))) @@ -258,3 +257,24 @@ 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))