From: Lutz Euler Date: Wed, 25 Apr 2012 22:49:06 +0000 (+0200) Subject: Micro-optimizations in MOVE-IMMEDIATE and MOVE-ARG on x86-64 X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=c50747a96774ec8164ead5e51d74a6d8bcf6e822;p=sbcl.git Micro-optimizations in MOVE-IMMEDIATE and MOVE-ARG on x86-64 In MOVE-IMMEDIATE, when the target is in memory, avoid using a temporary register for more values than currently: The MOV instruction can move immediate values of type (SIGNED-BYTE 32) into 64-bit memory locations, not only (SIGNED-BYTE 31). Simplify a TYPE-CASE in MOVE-ARG: merge two clauses that generated exactly the same MOV instruction; spare a call to MOVE-IMMEDIATE and get rid of two ugly literal 29s thereby. Add a test. --- diff --git a/src/compiler/x86-64/move.lisp b/src/compiler/x86-64/move.lisp index 7872710..cc0a777 100644 --- a/src/compiler/x86-64/move.lisp +++ b/src/compiler/x86-64/move.lisp @@ -129,7 +129,7 @@ (sc-is target signed-reg unsigned-reg descriptor-reg any-reg)) (inst mov target val)) ;; Likewise if the value is small enough. - ((typep val '(signed-byte 31)) + ((typep val '(signed-byte 32)) (inst mov target val)) ;; Otherwise go through the temporary register (tmp-tn @@ -159,10 +159,8 @@ (etypecase val ((integer 0 0) (zeroize y)) - ((or (signed-byte 29) (unsigned-byte 29)) - (inst mov y (fixnumize val))) (integer - (move-immediate y (fixnumize val))) + (inst mov y (fixnumize val))) (symbol (load-symbol y val)) (character diff --git a/tests/compiler.pure.lisp b/tests/compiler.pure.lisp index fe4bd64..68b37d1 100644 --- a/tests/compiler.pure.lisp +++ b/tests/compiler.pure.lisp @@ -4236,3 +4236,21 @@ (unless (= (funcall fun 16) (logand 15 (1- (ash 1 width)))) (push (cons width extra) result))))) (assert (null result)))) + +;; On x86-64 MOVE-IMMEDIATE of fixnum values into memory either directly +;; uses a MOV into memory or goes through a temporary register if the +;; value is larger than a certain number of bits. Check that it respects +;; the limits of immediate arguments to the MOV instruction (if not, the +;; assembler will fail an assertion) and doesn't have sign-extension +;; problems. (The test passes fixnum constants through the MOVE VOP +;; which calls MOVE-IMMEDIATE.) +(with-test (:name :constant-fixnum-move) + (let ((f (compile nil `(lambda (g) + (funcall g + ;; The first three args are + ;; uninteresting as they are + ;; passed in registers. + 1 2 3 + ,@(loop for i from 27 to 32 + collect (expt 2 i))))))) + (assert (every #'plusp (funcall f #'list)))))