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.
(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.
,(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))
(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))
\f
;;;; 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)
;;; 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"