Micro-optimize machine code for some register tests on x86[-64].
authorLutz Euler <lutz.euler@freenet.de>
Tue, 17 Apr 2012 18:52:09 +0000 (20:52 +0200)
committerLutz Euler <lutz.euler@freenet.de>
Tue, 17 Apr 2012 18:52:09 +0000 (20:52 +0200)
Replace all occurrences of (INST OR REG REG) with (INST TEST REG REG)
in VOPs and assembly routines. This removes, for the next read of REG,
the dependency on this instruction, allowing more instruction-level
parallelism, so is potentially faster. Moreover, most of the time the
next instruction is a conditional branch, which allows processors that
support macro-op fusion to fuse the TEST (but not the OR) with this
branch instruction, reducing the resources needed to decode and execute
the two instructions, which again is potentially faster.

src/assembly/x86-64/alloc.lisp
src/assembly/x86-64/assem-rtns.lisp
src/assembly/x86/alloc.lisp
src/assembly/x86/assem-rtns.lisp
src/compiler/x86-64/arith.lisp
src/compiler/x86-64/cell.lisp
src/compiler/x86-64/type-vops.lisp
src/compiler/x86/arith.lisp
src/compiler/x86/cell.lisp
src/compiler/x86/type-vops.lisp

index 35af80a..e40d380 100644 (file)
                ;; Now with the lock held, see if the symbol's tls index has been
                ;; set in the meantime.
                (loadw target other symbol-tls-index-slot other-pointer-lowtag)
-               (inst or target target)
+               (inst test target target)
                (inst jmp :ne release-tls-index-lock)
                ;; Allocate a new tls-index.
                (load-symbol-value target *free-tls-index*)
index 6799744..125c15f 100644 (file)
       (emit-error-break nil error-trap
                         (error-number-or-lose 'unseen-throw-tag-error)
                         (list target)))
-    (inst or catch catch)               ; check for NULL pointer
+    (inst test catch catch)             ; check for NULL pointer
     (inst jmp :z error))
 
   (inst cmp target (make-ea-for-object-slot catch catch-block-tag-slot 0))
   (declare (ignore start count))
 
   (let ((error (generate-error-code nil 'invalid-unwind-error)))
-    (inst or block block)               ; check for NULL pointer
+    (inst test block block)             ; check for NULL pointer
     (inst jmp :z error))
 
   (load-tl-symbol-value uwp *current-unwind-protect-block*)
index 84d49c5..3131e45 100644 (file)
                ;; Now with the lock held, see if the symbol's tls index has been
                ;; set in the meantime.
                (loadw target other symbol-tls-index-slot other-pointer-lowtag)
-               (inst or target target)
+               (inst test target target)
                (inst jmp :ne release-tls-index-lock)
                ;; Allocate a new tls-index.
                (load-symbol-value target *free-tls-index*)
index 1ef7ed0..1c23f0a 100644 (file)
       (emit-error-break nil error-trap
                         (error-number-or-lose 'unseen-throw-tag-error)
                         (list target)))
-    (inst or catch catch)               ; check for NULL pointer
+    (inst test catch catch)             ; check for NULL pointer
     (inst jmp :z error))
 
   (inst cmp target (make-ea-for-object-slot catch catch-block-tag-slot 0))
   (declare (ignore start count))
 
   (let ((error (generate-error-code nil 'invalid-unwind-error)))
-    (inst or block block)               ; check for NULL pointer
+    (inst test block block)             ; check for NULL pointer
     (inst jmp :z error))
 
   (load-tl-symbol-value uwp *current-unwind-protect-block*)
   (declare (ignore start count))
 
   (let ((error (generate-error-code nil 'invalid-unwind-error)))
-    (inst or block block)               ; check for NULL pointer
+    (inst test block block)             ; check for NULL pointer
     (inst jmp :z error))
 
   ;; Save all our registers, as we're about to clobber them.
index 4878c68..b8ee90c 100644 (file)
@@ -840,7 +840,7 @@ constant shift greater than word length")))
   (:generator 5
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns POSITIVE)
     (inst neg ecx)
     (inst cmp ecx 63)
@@ -869,7 +869,7 @@ constant shift greater than word length")))
   (:generator 5
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns POSITIVE)
     (inst neg ecx)
     (inst cmp ecx 63)
@@ -981,7 +981,7 @@ constant shift greater than word length")))
   (:generator 4
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns POSITIVE)
     (inst neg ecx)
     (zeroize zero)
@@ -1506,7 +1506,7 @@ constant shift greater than word length")))
   (:arg-types unsigned-num)
   (:conditional :ns)
   (:generator 3
-    (inst or digit digit)))
+    (inst test digit digit)))
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
index a27dc19..8744c26 100644 (file)
       (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
       (inst add bsp (* binding-size n-word-bytes))
       (store-binding-stack-pointer bsp)
-      (inst or tls-index tls-index)
+      (inst test tls-index tls-index)
       (inst jmp :ne tls-index-valid)
       (inst mov tls-index symbol)
       (inst lea temp-reg-tn
 
     LOOP
     (loadw symbol bsp (- binding-symbol-slot binding-size))
-    (inst or symbol symbol)
+    (inst test symbol symbol)
     (inst jmp :z SKIP)
     ;; Bind stack debug sentinels have the unbound marker in the symbol slot
     (inst cmp symbol unbound-marker-widetag)
index 12c09af..8e99ec1 100644 (file)
         ;; Get the second digit.
         (loadw rax-tn value (1+ bignum-digits-offset) other-pointer-lowtag)
         ;; All zeros, its an (unsigned-byte 64).
-        (inst or rax-tn rax-tn)
+        (inst test rax-tn rax-tn)
         (inst jmp :z yep)
         (inst jmp nope)
 
 
         ;; positive implies (unsigned-byte 64).
         (emit-label fixnum)
-        (inst or rax-tn rax-tn)
+        (inst test rax-tn rax-tn)
         (inst jmp (if not-p :s :ns) target)
 
         (emit-label not-target)))))
       ;; Get the second digit.
       (loadw rax-tn value (1+ bignum-digits-offset) other-pointer-lowtag)
       ;; All zeros, its an (unsigned-byte 64).
-      (inst or rax-tn rax-tn)
+      (inst test rax-tn rax-tn)
       (inst jmp :z yep)
       (inst jmp nope)
 
 
       ;; positive implies (unsigned-byte 64).
       (emit-label fixnum)
-      (inst or rax-tn rax-tn)
+      (inst test rax-tn rax-tn)
       (inst jmp :s nope)
 
       (emit-label yep)
index b451680..ab11950 100644 (file)
@@ -764,7 +764,7 @@ constant shift greater than word length")))
   (:generator 5
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns positive)
     (inst neg ecx)
     (inst cmp ecx 31)
@@ -793,7 +793,7 @@ constant shift greater than word length")))
   (:generator 5
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns positive)
     (inst neg ecx)
     (inst cmp ecx 31)
@@ -905,7 +905,7 @@ constant shift greater than word length")))
   (:generator 4
     (move result number)
     (move ecx amount)
-    (inst or ecx ecx)
+    (inst test ecx ecx)
     (inst jmp :ns positive)
     (inst neg ecx)
     (inst xor zero zero)
@@ -1464,7 +1464,7 @@ constant shift greater than word length")))
   (:arg-types unsigned-num)
   (:conditional :ns)
   (:generator 3
-    (inst or digit digit)))
+    (inst test digit digit)))
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
index 5be6b34..0239ac1 100644 (file)
       (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
       (inst add bsp (* binding-size n-word-bytes))
       (store-binding-stack-pointer bsp)
-      (inst or tls-index tls-index)
+      (inst test tls-index tls-index)
       (inst jmp :ne tls-index-valid)
       (inst mov tls-index symbol)
       (inst call (make-fixup
 
     LOOP
     (loadw symbol bsp (- binding-symbol-slot binding-size))
-    (inst or symbol symbol)
+    (inst test symbol symbol)
     (inst jmp :z skip)
     ;; Bind stack debug sentinels have the unbound marker in the symbol slot
     (inst cmp symbol unbound-marker-widetag)
index af66ab4..38d6adc 100644 (file)
         ;; Get the second digit.
         (loadw eax-tn value (1+ bignum-digits-offset) other-pointer-lowtag)
         ;; All zeros, its an (unsigned-byte 32).
-        (inst or eax-tn eax-tn)
+        (inst test eax-tn eax-tn)
         (inst jmp :z yep)
         (inst jmp nope)
 
 
         ;; positive implies (unsigned-byte 32).
         (emit-label fixnum)
-        (inst or eax-tn eax-tn)
+        (inst test eax-tn eax-tn)
         (inst jmp (if not-p :s :ns) target)
 
         (emit-label not-target)))))
       ;; Get the second digit.
       (loadw eax-tn value (1+ bignum-digits-offset) other-pointer-lowtag)
       ;; All zeros, its an (unsigned-byte 32).
-      (inst or eax-tn eax-tn)
+      (inst test eax-tn eax-tn)
       (inst jmp :z yep)
       (inst jmp nope)
 
 
       ;; positive implies (unsigned-byte 32).
       (emit-label fixnum)
-      (inst or eax-tn eax-tn)
+      (inst test eax-tn eax-tn)
       (inst jmp :s nope)
 
       (emit-label yep)