0.8.3.72:
[sbcl.git] / src / compiler / x86 / arith.lisp
index 0675614..af7da99 100644 (file)
   (define-binop logior 2 or)
   (define-binop logxor 2 xor))
 
-
 ;;; Special handling of add on the x86; can use lea to avoid a
 ;;; register load, otherwise it uses add.
 (define-vop (fast-+/fixnum=>fixnum fast-safe-arith-op)
     (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)
 (define-vop (fast-logxor-mod32-c/unsigned=>unsigned
              fast-logxor-c/unsigned=>unsigned)
   (:translate logxor-mod32))
+
+(define-source-transform logeqv (&rest args)
+  (if (oddp (length args))
+      `(logxor ,@args)
+      `(lognot (logxor ,@args))))
+(define-source-transform logandc1 (x y)
+  `(logand (lognot ,x) ,y))
+(define-source-transform logandc2 (x y)
+  `(logand ,x (lognot ,y)))
+(define-source-transform logorc1 (x y)
+  `(logior (lognot ,x) ,y))
+(define-source-transform logorc2 (x y)
+  `(logior ,x (lognot ,y)))
+(define-source-transform lognor (x y)
+  `(lognot (logior ,x ,y)))
+(define-source-transform lognand (x y)
+  `(lognot (logand ,x ,y)))
 \f
 ;;;; bignum stuff
 
   (foldable flushable))
 
 (defoptimizer (%lea derive-type) ((base index scale disp))
-  (when (and (constant-continuation-p scale)
-            (constant-continuation-p disp))
-    (let ((scale (continuation-value scale))
-         (disp (continuation-value disp))
-         (base-type (continuation-type base))
-         (index-type (continuation-type index)))
+  (when (and (constant-lvar-p scale)
+            (constant-lvar-p disp))
+    (let ((scale (lvar-value scale))
+         (disp (lvar-value disp))
+         (base-type (lvar-type base))
+         (index-type (lvar-type index)))
       (when (and (numeric-type-p base-type)
                 (numeric-type-p index-type))
        (let ((base-lo (numeric-type-low base-type))
                 ((unsigned-byte 32) (constant-arg (unsigned-byte 32)))
                 (unsigned-byte 32))
   "recode as leas, shifts and adds"
-  (let ((y (continuation-value y)))
+  (let ((y (lvar-value y)))
     (cond
       ((= y (ash 1 (integer-length y)))
        ;; there's a generic transform for y = 2^k