handle non-standard slot allocations when updating classes
[sbcl.git] / src / compiler / x86 / arith.lisp
index d557048..6965fee 100644 (file)
   (:note "inline fixnum arithmetic")
   (:generator 4
     (move r x)
-    (inst sar r 2)
+    (inst sar r n-fixnum-tag-bits)
     (inst imul r y)))
 
 (define-vop (fast-*-c/fixnum=>fixnum fast-safe-arith-op)
     (inst cdq)
     (inst idiv eax y)
     (if (location= quo eax)
-        (inst shl eax 2)
-        (inst lea quo (make-ea :dword :index eax :scale 4)))
+        (inst shl eax n-fixnum-tag-bits)
+        (inst lea quo (make-ea :dword :index eax
+                               :scale (ash 1 n-fixnum-tag-bits))))
     (move rem edx)))
 
 (define-vop (fast-truncate-c/fixnum=>fixnum fast-safe-arith-op)
     (inst mov y-arg (fixnumize y))
     (inst idiv eax y-arg)
     (if (location= quo eax)
-        (inst shl eax 2)
-        (inst lea quo (make-ea :dword :index eax :scale 4)))
+        (inst shl eax n-fixnum-tag-bits)
+        (inst lea quo (make-ea :dword :index eax
+                               :scale (ash 1 n-fixnum-tag-bits))))
     (move rem edx)))
 
 (define-vop (fast-truncate/unsigned=>unsigned fast-safe-arith-op)
                                        (location= number result)))))
   (:result-types tagged-num)
   (:note "inline ASH")
+  (:variant nil)
+  (:variant-vars modularp)
   (:generator 2
     (cond ((and (= amount 1) (not (location= number result)))
            (inst lea result (make-ea :dword :base number :index number)))
                         (inst sar result (- amount))
                         (inst and result (lognot fixnum-tag-mask)))))
                  ((plusp amount)
+                  (unless modularp
+                    (aver (not "Impossible: fixnum ASH should not be called with
+constant shift greater than word length")))
                   (if (sc-is result any-reg)
                       (inst xor result result)
                       (inst mov result 0)))
 \f
 ;;;; 32-bit logical operations
 
-(define-vop (merge-bits)
-  (:translate merge-bits)
-  (:args (shift :scs (signed-reg unsigned-reg) :target ecx)
-         (prev :scs (unsigned-reg) :target result)
-         (next :scs (unsigned-reg)))
-  (:arg-types tagged-num unsigned-num unsigned-num)
-  (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 0)) ecx)
-  (:results (result :scs (unsigned-reg) :from (:argument 1)))
-  (:result-types unsigned-num)
-  (:policy :fast-safe)
-  (:generator 4
-    (move ecx shift)
-    (move result prev)
-    (inst shrd result next :cl)))
-
 ;;; Only the lower 5 bits of the shift amount are significant.
 (define-vop (shift-towards-someplace)
   (:policy :fast-safe)
 
 (define-vop (fast-ash-left-smod30-c/fixnum=>fixnum
              fast-ash-c/fixnum=>fixnum)
+  (:variant :modular)
   (:translate ash-left-smod30))
 
 (define-vop (fast-ash-left-smod30/fixnum=>fixnum
     (move hi edx)
     (move lo eax)))
 
+#!+multiply-high-vops
+(define-vop (mulhi)
+  (:translate sb!kernel:%multiply-high)
+  (:policy :fast-safe)
+  (:args (x :scs (unsigned-reg) :target eax)
+         (y :scs (unsigned-reg unsigned-stack)))
+  (:arg-types unsigned-num unsigned-num)
+  (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0))
+              eax)
+  (:temporary (:sc unsigned-reg :offset edx-offset :from (:argument 1)
+                   :to (:result 0) :target hi) edx)
+  (:results (hi :scs (unsigned-reg)))
+  (:result-types unsigned-num)
+  (:generator 20
+    (move eax x)
+    (inst mul eax y)
+    (move hi edx)))
+
+#!+multiply-high-vops
+(define-vop (mulhi/fx)
+  (:translate sb!kernel:%multiply-high)
+  (:policy :fast-safe)
+  (:args (x :scs (any-reg) :target eax)
+         (y :scs (unsigned-reg unsigned-stack)))
+  (:arg-types positive-fixnum unsigned-num)
+  (:temporary (:sc any-reg :offset eax-offset :from (:argument 0)) eax)
+  (:temporary (:sc any-reg :offset edx-offset :from (:argument 1)
+                   :to (:result 0) :target hi) edx)
+  (:results (hi :scs (any-reg)))
+  (:result-types positive-fixnum)
+  (:generator 15
+    (move eax x)
+    (inst mul eax y)
+    (move hi edx)
+    (inst and hi (lognot fixnum-tag-mask))))
+
 (define-vop (bignum-lognot lognot-mod32/word=>unsigned)
   (:translate sb!bignum:%lognot))
 
   (:result-types unsigned-num)
   (:generator 1
     (move digit fixnum)
-    (inst sar digit 2)))
+    (inst sar digit n-fixnum-tag-bits)))
 
 (define-vop (bignum-floor)
-  (:translate sb!bignum:%floor)
+  (:translate sb!bignum:%bigfloor)
   (:policy :fast-safe)
   (:args (div-high :scs (unsigned-reg) :target edx)
          (div-low :scs (unsigned-reg) :target eax)
   (:generator 1
     (move res digit)
     (when (sc-is res any-reg control-stack)
-      (inst shl res 2))))
+      (inst shl res n-fixnum-tag-bits))))
 
 (define-vop (digit-ashr)
   (:translate sb!bignum:%ashr)