From: Christophe R. <cr...@us...> - 2003-09-04 15:05:44
|
Update of /cvsroot/sbcl/sbcl/src/compiler/x86 In directory sc8-pr-cvs1:/tmp/cvs-serv23423/src/compiler/x86 Modified Files: arith.lisp insts.lisp Log Message: 0.8.3.35: Since we're playing with backends... ... add the x86 CMOV instruction ... and a (disabled by default) VOP that uses it for ASH No, it's not noticeably faster; why do you ask? *sigh* Index: arith.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/x86/arith.lisp,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- arith.lisp 3 Sep 2003 16:52:24 -0000 1.16 +++ arith.lisp 4 Sep 2003 15:05:34 -0000 1.17 @@ -788,6 +788,40 @@ (inst shl result :cl) DONE)) + +;;; FIXME: before making knowledge of this too public, it needs to be +;;; fixed so that it's actually _faster_ than the non-CMOV version; at +;;; least on my Celeron-XXX laptop, this version is marginally slower +;;; than the above version with branches. -- CSR, 2003-09-04 +(define-vop (fast-cmov-ash/unsigned=>unsigned) + (:translate ash) + (:policy :fast-safe) + (:args (number :scs (unsigned-reg) :target result) + (amount :scs (signed-reg) :target ecx)) + (:arg-types unsigned-num signed-num) + (:results (result :scs (unsigned-reg) :from (:argument 0))) + (:result-types unsigned-num) + (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx) + (:temporary (:sc any-reg :from (:eval 0) :to (:eval 1)) zero) + (:note "inline ASH") + (:guard (member :cmov *backend-subfeatures*)) + (:generator 4 + (move result number) + (move ecx amount) + (inst or ecx ecx) + (inst jmp :ns positive) + (inst neg ecx) + (inst xor zero zero) + (inst shr result :cl) + (inst cmp ecx 31) + (inst cmov :nbe result zero) + (inst jmp done) + + POSITIVE + ;; The result-type ensures us that this shift will not overflow. + (inst shl result :cl) + + DONE)) ;;; Note: documentation for this function is wrong - rtfm (define-vop (signed-byte-32-len) Index: insts.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/x86/insts.lisp,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- insts.lisp 29 May 2003 12:28:02 -0000 1.26 +++ insts.lisp 4 Sep 2003 15:05:34 -0000 1.27 @@ -588,6 +588,16 @@ :type 'byte-reg/mem) (reg :field (byte 3 19) :value #b000)) +(sb!disassem:define-instruction-format (cond-move 24 + :default-printer + '('cmov cc :tab reg ", " reg/mem)) + (prefix :field (byte 8 0) :value #b00001111) + (op :field (byte 4 12) :value #b0100) + (cc :field (byte 4 8) :type 'condition-code) + (reg/mem :fields (list (byte 2 22) (byte 3 16)) + :type 'reg/mem) + (reg :field (byte 3 19) :type 'reg)) + (sb!disassem:define-instruction-format (enter-format 32 :default-printer '(:name :tab disp @@ -1784,6 +1794,18 @@ (emit-byte segment #b11100000) (emit-byte-displacement-backpatch segment target))) +;;;; conditional move +(define-instruction cmov (segment cond dst src) + (:printer cond-move ()) + (:emitter + (aver (register-p dst)) + (let ((size (matching-operand-size dst src))) + (aver (or (eq size :word) (eq size :dword))) + (maybe-emit-operand-size-prefix segment size)) + (emit-byte segment #b00001111) + (emit-byte segment (dpb (conditional-opcode cond) (byte 4 0) #b01000000)) + (emit-ea segment src (reg-tn-encoding dst)))) + ;;;; conditional byte set (define-instruction set (segment dst cond) |