From 18775b5e3c9a75f5301e09ddef649f2f35ab9752 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 13 Apr 2012 11:05:18 -0400 Subject: [PATCH] use LEA Y, [X+X] instead of LEA Y, [X*2] where appropriate on x86-64 The former instruction is slightly smaller. Keep the old form around for people who want to compile x86-64 with smaller fixnums. --- src/compiler/x86-64/arith.lisp | 12 ++++++++---- src/compiler/x86-64/move.lisp | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/compiler/x86-64/arith.lisp b/src/compiler/x86-64/arith.lisp index 0e0be28..4878c68 100644 --- a/src/compiler/x86-64/arith.lisp +++ b/src/compiler/x86-64/arith.lisp @@ -510,8 +510,10 @@ (inst idiv eax y) (if (location= quo eax) (inst shl eax n-fixnum-tag-bits) - (inst lea quo (make-ea :qword :index eax - :scale (ash 1 n-fixnum-tag-bits)))) + (if (= n-fixnum-tag-bits 1) + (inst lea quo (make-ea :qword :base eax :index eax)) + (inst lea quo (make-ea :qword :index eax + :scale (ash 1 n-fixnum-tag-bits))))) (move rem edx))) (define-vop (fast-truncate-c/fixnum=>fixnum fast-safe-arith-op) @@ -539,8 +541,10 @@ (inst idiv eax y-arg) (if (location= quo eax) (inst shl eax n-fixnum-tag-bits) - (inst lea quo (make-ea :qword :index eax - :scale (ash 1 n-fixnum-tag-bits)))) + (if (= n-fixnum-tag-bits 1) + (inst lea quo (make-ea :qword :base eax :index eax)) + (inst lea quo (make-ea :qword :index eax + :scale (ash 1 n-fixnum-tag-bits))))) (move rem edx))) (define-vop (fast-truncate/unsigned=>unsigned fast-safe-arith-op) diff --git a/src/compiler/x86-64/move.lisp b/src/compiler/x86-64/move.lisp index 1b084d0..7872710 100644 --- a/src/compiler/x86-64/move.lisp +++ b/src/compiler/x86-64/move.lisp @@ -290,9 +290,10 @@ (:generator 1 (cond ((and (sc-is x signed-reg unsigned-reg) (not (location= x y))) - ;; Uses 7 bytes, but faster on the Pentium - (inst lea y (make-ea :qword :index x - :scale (ash 1 n-fixnum-tag-bits)))) + (if (= n-fixnum-tag-bits 1) + (inst lea y (make-ea :qword :base x :index x)) + (inst lea y (make-ea :qword :index x + :scale (ash 1 n-fixnum-tag-bits))))) (t ;; Uses: If x is a reg 2 + 3; if x = y uses only 3 bytes (move y x) @@ -353,10 +354,14 @@ ;; you change stuff here, make sure the sign flag doesn't get ;; overwritten before the CALL! (inst test x y) - ;; Faster but bigger then SHL Y 4. The cost of doing this - ;; speculatively should be noise compared to bignum consing if - ;; that is needed and saves one branch. - (inst lea y (make-ea :qword :index x :scale (ash 1 n-fixnum-tag-bits))) + ;; Using LEA is faster but bigger than MOV+SHL; it also doesn't + ;; twiddle the sign flag. The cost of doing this speculatively + ;; should be noise compared to bignum consing if that is needed + ;; and saves one branch. + (if (= n-fixnum-tag-bits 1) + (inst lea y (make-ea :qword :base x :index x)) + (inst lea y (make-ea :qword :index x + :scale (ash 1 n-fixnum-tag-bits)))) (inst jmp :z done) (inst mov y x) (inst lea temp-reg-tn -- 1.7.10.4