1.0.10.5: dynamic-extent CONS
[sbcl.git] / src / compiler / x86 / arith.lisp
index ad66b62..7511b32 100644 (file)
            (inst lea result (make-ea :dword :index number :scale 8)))
           (t
            (move result number)
-           (cond ((plusp amount)
-                  ;; We don't have to worry about overflow because of the
-                  ;; result type restriction.
-                  (inst shl result amount))
-                 (t
-                  ;; If the amount is greater than 31, only shift by 31. We
-                  ;; have to do this because the shift instructions only look
-                  ;; at the low five bits of the result.
-                  (inst sar result (min 31 (- amount)))
-                  ;; Fixnum correction.
-                  (inst and result (lognot fixnum-tag-mask))))))))
+           (cond ((< -32 amount 32)
+                  ;; this code is used both in ASH and ASH-SMOD30, so
+                  ;; be careful
+                  (if (plusp amount)
+                      (inst shl result amount)
+                      (progn
+                        (inst sar result (- amount))
+                        (inst and result (lognot fixnum-tag-mask)))))
+                 ((plusp amount)
+                  (if (sc-is result any-reg)
+                      (inst xor result result)
+                      (inst mov result 0)))
+                 (t (inst sar result 31)
+                    (inst and result (lognot fixnum-tag-mask))))))))
 
 (define-vop (fast-ash-left/fixnum=>fixnum)
   (:translate ash)
   (:results (y :scs (unsigned-reg) :from (:eval 0)))
   (:result-types unsigned-num)
   (:generator 50
-    (inst mov k (make-ea :dword :base state
-                         :disp (- (* (+ 2 vector-data-offset)
-                                     n-word-bytes)
-                                  other-pointer-lowtag)))
+    (loadw k state (+ 2 vector-data-offset) other-pointer-lowtag)
     (inst cmp k 624)
     (inst jmp :ne no-update)
     (inst mov tmp state)        ; The state is passed in EAX.
     (inst xor k k)
     NO-UPDATE
     ;; y = ptgfsr[k++];
-    (inst mov y (make-ea :dword :base state :index k :scale 4
-                         :disp (- (* (+ 3 vector-data-offset)
-                                     n-word-bytes)
-                                  other-pointer-lowtag)))
+    (inst mov y (make-ea-for-vector-data state :index k :offset 3))
     ;; y ^= (y >> 11);
     (inst shr y 11)
-    (inst xor y (make-ea :dword :base state :index k :scale 4
-                         :disp (- (* (+ 3 vector-data-offset)
-                                     n-word-bytes)
-                                  other-pointer-lowtag)))
+    (inst xor y (make-ea-for-vector-data state :index k :offset 3))
     ;; y ^= (y << 7) & #x9d2c5680
     (inst mov tmp y)
     (inst inc k)
     (inst shl tmp 7)
-    (inst mov (make-ea :dword :base state
-                       :disp (- (* (+ 2 vector-data-offset)
-                                   n-word-bytes)
-                                other-pointer-lowtag))
-          k)
+    (storew k state (+ 2 vector-data-offset) other-pointer-lowtag)
     (inst and tmp #x9d2c5680)
     (inst xor y tmp)
     ;; y ^= (y << 15) & #xefc60000