From 37b93fe46f304244d1c69c06b82a22252e393630 Mon Sep 17 00:00:00 2001 From: Lutz Euler Date: Tue, 17 Apr 2012 20:52:09 +0200 Subject: [PATCH] Micro-optimize machine code for some register tests on x86[-64]. 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 | 2 +- src/assembly/x86-64/assem-rtns.lisp | 4 ++-- src/assembly/x86/alloc.lisp | 2 +- src/assembly/x86/assem-rtns.lisp | 6 +++--- src/compiler/x86-64/arith.lisp | 8 ++++---- src/compiler/x86-64/cell.lisp | 4 ++-- src/compiler/x86-64/type-vops.lisp | 8 ++++---- src/compiler/x86/arith.lisp | 8 ++++---- src/compiler/x86/cell.lisp | 4 ++-- src/compiler/x86/type-vops.lisp | 8 ++++---- 10 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/assembly/x86-64/alloc.lisp b/src/assembly/x86-64/alloc.lisp index 35af80a..e40d380 100644 --- a/src/assembly/x86-64/alloc.lisp +++ b/src/assembly/x86-64/alloc.lisp @@ -103,7 +103,7 @@ ;; 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*) diff --git a/src/assembly/x86-64/assem-rtns.lisp b/src/assembly/x86-64/assem-rtns.lisp index 6799744..125c15f 100644 --- a/src/assembly/x86-64/assem-rtns.lisp +++ b/src/assembly/x86-64/assem-rtns.lisp @@ -243,7 +243,7 @@ (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)) @@ -270,7 +270,7 @@ (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*) diff --git a/src/assembly/x86/alloc.lisp b/src/assembly/x86/alloc.lisp index 84d49c5..3131e45 100644 --- a/src/assembly/x86/alloc.lisp +++ b/src/assembly/x86/alloc.lisp @@ -111,7 +111,7 @@ ;; 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*) diff --git a/src/assembly/x86/assem-rtns.lisp b/src/assembly/x86/assem-rtns.lisp index 1ef7ed0..1c23f0a 100644 --- a/src/assembly/x86/assem-rtns.lisp +++ b/src/assembly/x86/assem-rtns.lisp @@ -236,7 +236,7 @@ (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)) @@ -264,7 +264,7 @@ (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*) @@ -309,7 +309,7 @@ (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. diff --git a/src/compiler/x86-64/arith.lisp b/src/compiler/x86-64/arith.lisp index 4878c68..b8ee90c 100644 --- a/src/compiler/x86-64/arith.lisp +++ b/src/compiler/x86-64/arith.lisp @@ -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 diff --git a/src/compiler/x86-64/cell.lisp b/src/compiler/x86-64/cell.lisp index a27dc19..8744c26 100644 --- a/src/compiler/x86-64/cell.lisp +++ b/src/compiler/x86-64/cell.lisp @@ -307,7 +307,7 @@ (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 @@ -390,7 +390,7 @@ 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) diff --git a/src/compiler/x86-64/type-vops.lisp b/src/compiler/x86-64/type-vops.lisp index 12c09af..8e99ec1 100644 --- a/src/compiler/x86-64/type-vops.lisp +++ b/src/compiler/x86-64/type-vops.lisp @@ -313,7 +313,7 @@ ;; 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) @@ -323,7 +323,7 @@ ;; 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))))) @@ -356,7 +356,7 @@ ;; 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) @@ -366,7 +366,7 @@ ;; 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) diff --git a/src/compiler/x86/arith.lisp b/src/compiler/x86/arith.lisp index b451680..ab11950 100644 --- a/src/compiler/x86/arith.lisp +++ b/src/compiler/x86/arith.lisp @@ -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 diff --git a/src/compiler/x86/cell.lisp b/src/compiler/x86/cell.lisp index 5be6b34..0239ac1 100644 --- a/src/compiler/x86/cell.lisp +++ b/src/compiler/x86/cell.lisp @@ -286,7 +286,7 @@ (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 @@ -359,7 +359,7 @@ 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) diff --git a/src/compiler/x86/type-vops.lisp b/src/compiler/x86/type-vops.lisp index af66ab4..38d6adc 100644 --- a/src/compiler/x86/type-vops.lisp +++ b/src/compiler/x86/type-vops.lisp @@ -312,7 +312,7 @@ ;; 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) @@ -322,7 +322,7 @@ ;; 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))))) @@ -355,7 +355,7 @@ ;; 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) @@ -365,7 +365,7 @@ ;; 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) -- 1.7.10.4