X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fpred.lisp;h=8f2abbd8d21c0fc572d24fdc40fed86cf141033b;hb=74cf7a4d01664fbf72a662ba093ad67ca243b524;hp=8c9b2fd87114696175c7bac87660a1d95432ba0e;hpb=91ee7afd75d8b282829daa647d0a8f1469336a77;p=sbcl.git diff --git a/src/compiler/x86-64/pred.lisp b/src/compiler/x86-64/pred.lisp index 8c9b2fd..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)) @@ -180,35 +179,26 @@ (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)) ;;;; conditional VOPs @@ -226,7 +216,7 @@ (:conditional :e) (:policy :fast-safe) (:translate eq) - (:generator 3 + (:generator 6 (cond ((sc-is y immediate) (let ((val (tn-value y))) @@ -267,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))