Microoptimization for code size in floating point comparisons on x86-64
authorLutz Euler <lutz.euler@freenet.de>
Tue, 30 Aug 2011 22:41:38 +0000 (18:41 -0400)
committerPaul Khuong <pvk@pvk.ca>
Tue, 30 Aug 2011 22:41:38 +0000 (18:41 -0400)
This affects EQL on real and complex floats and "=" on floats when at
least one of the two arguments is complex.

Use a 32-bit register as the destination of the MOVMSKP[SD] and the
source of the integer comparison instead of a 64-bit one. This doesn't
change the semantics but makes both instruction's encodings shorter.
If the register is EAX do the comparison on AL as this additionally
shortens the encoding.

Before:

  660F76C1         PCMPEQD XMM0, XMM1
  480F50C0         MOVMSKPS RAX, XMM0
  4883F80F         CMP RAX, 15

After:

  660F76C1         PCMPEQD XMM0, XMM1
  0F50C0           MOVMSKPS EAX, XMM0
  3C0F             CMP AL, 15

src/compiler/x86-64/float.lisp

index c74c8c7..0a03d50 100644 (file)
                             :load-if (not (sc-is y ,constant-sc))))
                   (:arg-types ,type ,type)
                   (:temporary (:sc ,sc :from :eval) mask)
-                  (:temporary (:sc any-reg) bits)
+                  (:temporary (:sc dword-reg) bits)
                   (:conditional :e)
                   (:generator ,cost
                     (when (or (location= y mask)
                       (setf y (register-inline-constant :aligned (tn-value y))))
                     (inst pcmpeqd mask y)
                     (inst movmskps bits mask)
-                    (inst cmp bits #b1111)))))
+                    (inst cmp (if (location= bits eax-tn) al-tn bits)
+                          #b1111)))))
   (define-float-eql eql/single-float 4
     single-reg fp-single-immediate single-float)
   (define-float-eql eql/double-float 4
                               :load-if (not (sc-is y ,complex-constant-sc))))
                     (:arg-types ,complex-type ,complex-type)
                     (:temporary (:sc ,complex-sc :from :eval) cmp)
-                    (:temporary (:sc unsigned-reg) bits)
+                    (:temporary (:sc dword-reg) bits)
                     (:info)
                     (:conditional :e)
                     (:generator 3
                       (note-this-location vop :internal-error)
                       (inst ,cmp-inst :eq cmp y)
                       (inst ,mask-inst bits cmp)
-                      (inst cmp bits ,mask)))
+                      (inst cmp (if (location= bits eax-tn) al-tn bits)
+                            ,mask)))
                   (define-vop (,complex-real-name ,complex-complex-name)
                     (:args (x :scs (,complex-sc ,complex-constant-sc)
                               :target cmp