From fd63d6aad4a5a3b171eafb56b1b6bd502e501281 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Sun, 17 Sep 2006 02:31:13 +0000 Subject: [PATCH] 0.9.16.34: Improve code generation for LOGTEST on x86. * Use the logic the fixnum test VOPs use for emitting small TEST instructions in the LOGTEST VOPs as well; * Change {ODD,EVEN}P source transforms to use LOGTEST. --- src/compiler/srctran.lisp | 4 ++-- src/compiler/x86/arith.lisp | 7 ++++--- src/compiler/x86/insts.lisp | 24 ++++++++++++++++++++++++ src/compiler/x86/type-vops.lisp | 19 +------------------ version.lisp-expr | 2 +- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index 8897534..d93c082 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -183,8 +183,8 @@ (define-source-transform 1+ (x) `(+ ,x 1)) (define-source-transform 1- (x) `(- ,x 1)) -(define-source-transform oddp (x) `(not (zerop (logand ,x 1)))) -(define-source-transform evenp (x) `(zerop (logand ,x 1))) +(define-source-transform oddp (x) `(logtest ,x 1)) +(define-source-transform evenp (x) `(not (logtest ,x 1))) ;;; Note that all the integer division functions are available for ;;; inline expansion. diff --git a/src/compiler/x86/arith.lisp b/src/compiler/x86/arith.lisp index ffd540a..1b29e8d 100644 --- a/src/compiler/x86/arith.lisp +++ b/src/compiler/x86/arith.lisp @@ -1060,9 +1060,10 @@ ,(symbolicate "FAST-CONDITIONAL" suffix)) (:translate logtest) (:generator ,cost - (inst test x ,(if (eq suffix '-c/fixnum) - '(fixnumize y) - 'y)) + (emit-optimized-test-inst x + ,(if (eq suffix '-c/fixnum) + '(fixnumize y) + 'y)) (inst jmp (if not-p :e :ne) target))))))) (define-logtest-vops)) diff --git a/src/compiler/x86/insts.lisp b/src/compiler/x86/insts.lisp index e823a2a..a7873ed 100644 --- a/src/compiler/x86/insts.lisp +++ b/src/compiler/x86/insts.lisp @@ -1533,6 +1533,30 @@ (t (error "bogus operands for TEST: ~S and ~S" this that))))))) +;;; Emit the most compact form of the test immediate instruction, +;;; using an 8 bit test when the immediate is only 8 bits and the +;;; value is one of the four low registers (eax, ebx, ecx, edx) or the +;;; control stack. +(defun emit-optimized-test-inst (x y) + (typecase y + ((unsigned-byte 7) + (let ((offset (tn-offset x))) + (cond ((and (sc-is x any-reg descriptor-reg) + (or (= offset eax-offset) (= offset ebx-offset) + (= offset ecx-offset) (= offset edx-offset))) + (inst test (make-random-tn :kind :normal + :sc (sc-or-lose 'byte-reg) + :offset offset) + y)) + ((sc-is x control-stack) + (inst test (make-ea :byte :base ebp-tn + :disp (- (* (1+ offset) n-word-bytes))) + y)) + (t + (inst test x y))))) + (t + (inst test x y)))) + (define-instruction or (segment dst src) (:printer-list (arith-inst-printer-list #b001)) diff --git a/src/compiler/x86/type-vops.lisp b/src/compiler/x86/type-vops.lisp index 6c9e10b..4b8cd45 100644 --- a/src/compiler/x86/type-vops.lisp +++ b/src/compiler/x86/type-vops.lisp @@ -13,25 +13,8 @@ ;;;; test generation utilities -;;; Emit the most compact form of the test immediate instruction, -;;; using an 8 bit test when the immediate is only 8 bits and the -;;; value is one of the four low registers (eax, ebx, ecx, edx) or the -;;; control stack. (defun generate-fixnum-test (value) - (let ((offset (tn-offset value))) - (cond ((and (sc-is value any-reg descriptor-reg) - (or (= offset eax-offset) (= offset ebx-offset) - (= offset ecx-offset) (= offset edx-offset))) - (inst test (make-random-tn :kind :normal - :sc (sc-or-lose 'byte-reg) - :offset offset) - 3)) - ((sc-is value control-stack) - (inst test (make-ea :byte :base ebp-tn - :disp (- (* (1+ offset) n-word-bytes))) - 3)) - (t - (inst test value 3))))) + (emit-optimized-test-inst value 3)) (defun %test-fixnum (value target not-p) (generate-fixnum-test value) diff --git a/version.lisp-expr b/version.lisp-expr index 47a3786..3a09cce 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.9.16.33" +"0.9.16.34" -- 1.7.10.4