0.8.3.35:
authorChristophe Rhodes <csr21@cam.ac.uk>
Thu, 4 Sep 2003 15:05:34 +0000 (15:05 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Thu, 4 Sep 2003 15:05:34 +0000 (15:05 +0000)
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*

src/compiler/x86/arith.lisp
src/compiler/x86/insts.lisp
version.lisp-expr

index 0675614..88c8122 100644 (file)
     (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))
 \f
 ;;; Note: documentation for this function is wrong - rtfm
 (define-vop (signed-byte-32-len)
index c64e761..59e7a7d 100644 (file)
           :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
    (emit-byte segment #b11100000)
    (emit-byte-displacement-backpatch segment target)))
 \f
+;;;; 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)
index ef9aeea..b7b69a0 100644 (file)
@@ -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.8.3.34"
+"0.8.3.35"