0.8.4.11:
[sbcl.git] / src / compiler / alpha / arith.lisp
index 82951bb..c680c61 100644 (file)
@@ -1,27 +1,17 @@
-;;; -*- Package: ALPHA; Log: C.Log -*-
-;;;
-;;; **********************************************************************
-;;; This code was written as part of the CMU Common Lisp project at
-;;; Carnegie Mellon University, and has been placed in the public domain.
-;;;
+;;;; the VM definition arithmetic VOPs for the Alpha
 
 
-;;;
-;;; **********************************************************************
-;;;
-;;; $Header$
-;;;
-;;;    This file contains the VM definition arithmetic VOPs for the MIPS.
-;;;
-;;; Written by Rob MacLachlan
-;;; Converted by Sean Hallgren
-;;; 
+;;;; This software is part of the SBCL system. See the README file for
+;;;; more information.
+;;;;
+;;;; This software is derived from the CMU CL system, which was
+;;;; written at Carnegie Mellon University and released into the
+;;;; public domain. The software is in the public domain and is
+;;;; provided with absolutely no warranty. See the COPYING and CREDITS
+;;;; files for more information.
 
 (in-package "SB!VM")
 
 (in-package "SB!VM")
-
-
-
 \f
 \f
-;;;; Unary operations.
+;;;; unary operations
 
 (define-vop (fixnum-unop)
   (:args (x :scs (any-reg)))
 
 (define-vop (fixnum-unop)
   (:args (x :scs (any-reg)))
@@ -34,7 +24,7 @@
 (define-vop (signed-unop)
   (:args (x :scs (signed-reg)))
   (:results (res :scs (signed-reg)))
 (define-vop (signed-unop)
   (:args (x :scs (signed-reg)))
   (:results (res :scs (signed-reg)))
-  (:note "inline (signed-byte 32) arithmetic")
+  (:note "inline (signed-byte 64) arithmetic")
   (:arg-types signed-num)
   (:result-types signed-num)
   (:policy :fast-safe))
   (:arg-types signed-num)
   (:result-types signed-num)
   (:policy :fast-safe))
   (:translate lognot)
   (:generator 1
     (inst not x res)))
   (:translate lognot)
   (:generator 1
     (inst not x res)))
-
-
 \f
 \f
-;;;; Binary fixnum operations.
+;;;; binary fixnum operations
 
 ;;; Assume that any constant operand is the second arg...
 
 
 ;;; Assume that any constant operand is the second arg...
 
@@ -82,7 +70,7 @@
   (:arg-types unsigned-num unsigned-num)
   (:results (r :scs (unsigned-reg)))
   (:result-types unsigned-num)
   (:arg-types unsigned-num unsigned-num)
   (:results (r :scs (unsigned-reg)))
   (:result-types unsigned-num)
-  (:note "inline (unsigned-byte 32) arithmetic")
+  (:note "inline (unsigned-byte 64) arithmetic")
   (:effects)
   (:affected)
   (:policy :fast-safe))
   (:effects)
   (:affected)
   (:policy :fast-safe))
@@ -93,7 +81,7 @@
   (:arg-types signed-num signed-num)
   (:results (r :scs (signed-reg)))
   (:result-types signed-num)
   (:arg-types signed-num signed-num)
   (:results (r :scs (signed-reg)))
   (:result-types signed-num)
-  (:note "inline (signed-byte 32) arithmetic")
+  (:note "inline (signed-byte 64) arithmetic")
   (:effects)
   (:affected)
   (:policy :fast-safe))
   (:effects)
   (:affected)
   (:policy :fast-safe))
   (:info y)
   (:arg-types tagged-num (:constant integer)))
 
   (:info y)
   (:arg-types tagged-num (:constant integer)))
 
-(defmacro define-binop (translate cost untagged-cost op
-                                 tagged-type untagged-type)
+(defmacro define-binop (translate cost untagged-cost op 
+                       tagged-type untagged-type
+                       &optional arg-swap restore-fixnum-mask)
   `(progn
      (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")
                  fast-fixnum-binop)
   `(progn
      (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")
                  fast-fixnum-binop)
-       (:args (x :target r :scs (any-reg))
-             (y :target r :scs (any-reg)))
+       ,@(when restore-fixnum-mask
+          `((:temporary (:sc non-descriptor-reg) temp)))
+       (:args (x ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg))
+             (y ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg)))
        (:translate ,translate)
        (:generator ,(1+ cost)
        (:translate ,translate)
        (:generator ,(1+ cost)
-        (inst ,op x y r)))
+        ,(if arg-swap
+             `(inst ,op y x ,(if restore-fixnum-mask 'temp 'r))
+             `(inst ,op x y ,(if restore-fixnum-mask 'temp 'r)))
+        ,@(when restore-fixnum-mask
+            `((inst bic temp #.(ash lowtag-mask -1) r)))))
      (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")
                  fast-signed-binop)
        (:args (x :target r :scs (signed-reg))
              (y :target r :scs (signed-reg)))
        (:translate ,translate)
        (:generator ,(1+ untagged-cost)
      (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")
                  fast-signed-binop)
        (:args (x :target r :scs (signed-reg))
              (y :target r :scs (signed-reg)))
        (:translate ,translate)
        (:generator ,(1+ untagged-cost)
-        (inst ,op x y r)))
+        ,(if arg-swap
+             `(inst ,op y x r)
+             `(inst ,op x y r))))
      (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED")
                  fast-unsigned-binop)
        (:args (x :target r :scs (unsigned-reg))
              (y :target r :scs (unsigned-reg)))
        (:translate ,translate)
        (:generator ,(1+ untagged-cost)
      (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED")
                  fast-unsigned-binop)
        (:args (x :target r :scs (unsigned-reg))
              (y :target r :scs (unsigned-reg)))
        (:translate ,translate)
        (:generator ,(1+ untagged-cost)
-        (inst ,op x y r)))
-     ,@(when tagged-type
+        ,(if arg-swap
+             `(inst ,op y x r)
+             `(inst ,op x y r))))
+     ,@(when (and tagged-type (not arg-swap))
         `((define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")
                        fast-fixnum-c-binop)
         `((define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")
                        fast-fixnum-c-binop)
-                      (:arg-types tagged-num (:constant ,tagged-type))
+            (:arg-types tagged-num (:constant ,tagged-type))
+            ,@(when restore-fixnum-mask
+                `((:temporary (:sc non-descriptor-reg) temp)))
             (:translate ,translate)
             (:generator ,cost
             (:translate ,translate)
             (:generator ,cost
-                        (inst ,op x (fixnumize y) r)))))
-     ,@(when untagged-type
+               (inst ,op x (fixnumize y) ,(if restore-fixnum-mask 'temp 'r))
+               ,@(when restore-fixnum-mask
+                   `((inst bic temp #.(ash lowtag-mask -1) r)))))))
+     ,@(when (and untagged-type (not arg-swap))
         `((define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
                        fast-signed-c-binop)
         `((define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
                        fast-signed-c-binop)
-                      (:arg-types signed-num (:constant ,untagged-type))
+            (:arg-types signed-num (:constant ,untagged-type))
             (:translate ,translate)
             (:generator ,untagged-cost
             (:translate ,translate)
             (:generator ,untagged-cost
-                        (inst ,op x y r)))
+               (inst ,op x y r)))
           (define-vop (,(symbolicate "FAST-" translate
                                      "-C/UNSIGNED=>UNSIGNED")
                        fast-unsigned-c-binop)
           (define-vop (,(symbolicate "FAST-" translate
                                      "-C/UNSIGNED=>UNSIGNED")
                        fast-unsigned-c-binop)
-                      (:arg-types unsigned-num (:constant ,untagged-type))
+            (:arg-types unsigned-num (:constant ,untagged-type))
             (:translate ,translate)
             (:generator ,untagged-cost
             (:translate ,translate)
             (:generator ,untagged-cost
-                        (inst ,op x y r)))))))
+               (inst ,op x y r)))))))
 
 (define-binop + 1 5 addq (unsigned-byte 6) (unsigned-byte 8))
 (define-binop - 1 5 subq (unsigned-byte 6) (unsigned-byte 8))
 
 (define-binop + 1 5 addq (unsigned-byte 6) (unsigned-byte 8))
 (define-binop - 1 5 subq (unsigned-byte 6) (unsigned-byte 8))
-(define-binop logior 1 3 bis (unsigned-byte 6) (unsigned-byte 8))
-(define-binop lognor 1 3 ornot (unsigned-byte 6) (unsigned-byte 8))
 (define-binop logand 1 3 and (unsigned-byte 6) (unsigned-byte 8))
 (define-binop logand 1 3 and (unsigned-byte 6) (unsigned-byte 8))
+(define-binop logandc1 1 3 bic (unsigned-byte 6) (unsigned-byte 8) t)
+(define-binop logandc2 1 3 bic (unsigned-byte 6) (unsigned-byte 8))
+(define-binop logior 1 3 bis (unsigned-byte 6) (unsigned-byte 8))
+(define-binop logorc1 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) t t)
+(define-binop logorc2 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) nil t)
 (define-binop logxor 1 3 xor (unsigned-byte 6) (unsigned-byte 8))
 (define-binop logxor 1 3 xor (unsigned-byte 6) (unsigned-byte 8))
+(define-binop logeqv 1 3 eqv (unsigned-byte 6) (unsigned-byte 8) nil t)
+
+;;; special cases for LOGAND where we can use a mask operation
+(define-vop (fast-logand-c-mask/unsigned=>unsigned fast-unsigned-c-binop)
+  (:translate logand)
+  (:arg-types unsigned-num
+             (:constant (or (integer #xffffffff #xffffffff)
+                            (integer #xffffffff00000000 #xffffffff00000000))))
+  (:generator 1
+    (ecase y
+      (#xffffffff (inst mskll x 4 r))
+      (#xffffffff00000000 (inst mskll x 0 r)))))
+\f
+;;;; shifting
 
 
+(define-vop (fast-ash/unsigned=>unsigned)
+  (:note "inline ASH")
+  (:args (number :scs (unsigned-reg) :to :save)
+        (amount :scs (signed-reg)))
+  (:arg-types unsigned-num signed-num)
+  (:results (result :scs (unsigned-reg)))
+  (:result-types unsigned-num)
+  (:translate ash)
+  (:policy :fast-safe)
+  (:temporary (:sc non-descriptor-reg) ndesc)
+  (:temporary (:sc non-descriptor-reg) temp)
+  (:generator 3
+    (inst bge amount positive)
+    (inst subq zero-tn amount ndesc)
+    (inst cmplt ndesc 64 temp)
+    (inst srl number ndesc result)
+    ;; FIXME: this looks like a candidate for a conditional move --
+    ;; CSR, 2003-09-10
+    (inst bne temp done)
+    (move zero-tn result)
+    (inst br zero-tn done)
+      
+    POSITIVE
+    (inst sll number amount result)
+      
+    DONE))
 
 
-;;; Shifting
-
-
-(define-vop (fast-ash)
+(define-vop (fast-ash/signed=>signed)
   (:note "inline ASH")
   (:note "inline ASH")
-  (:args (number :scs (signed-reg unsigned-reg) :to :save)
+  (:args (number :scs (signed-reg) :to :save)
         (amount :scs (signed-reg)))
         (amount :scs (signed-reg)))
-  (:arg-types (:or signed-num unsigned-num) signed-num)
-  (:results (result :scs (signed-reg unsigned-reg)))
-  (:result-types (:or signed-num unsigned-num))
+  (:arg-types signed-num signed-num)
+  (:results (result :scs (signed-reg)))
+  (:result-types signed-num)
   (:translate ash)
   (:policy :fast-safe)
   (:temporary (:sc non-descriptor-reg) ndesc)
   (:translate ash)
   (:policy :fast-safe)
   (:temporary (:sc non-descriptor-reg) ndesc)
-  (:temporary (:sc non-descriptor-reg :to :eval) temp)
+  (:temporary (:sc non-descriptor-reg) temp)
   (:generator 3
     (inst bge amount positive)
     (inst subq zero-tn amount ndesc)
   (:generator 3
     (inst bge amount positive)
     (inst subq zero-tn amount ndesc)
-    (inst cmplt ndesc 31 temp)
-    (sc-case number
-      (signed-reg (inst sra number ndesc result))
-      (unsigned-reg (inst srl number ndesc result)))
+    (inst cmplt ndesc 63 temp)
+    (inst sra number ndesc result)
     (inst bne temp done)
     (inst bne temp done)
-    (sc-case number
-      (signed-reg (inst sra number 31 result))
-      (unsigned-reg (inst srl number 31 result)))
+    (inst sra number 63 result)
     (inst br zero-tn done)
       
     POSITIVE
     (inst br zero-tn done)
       
     POSITIVE
-    ;; The result-type assures us that this shift will not overflow.
     (inst sll number amount result)
       
     DONE))
 
     (inst sll number amount result)
       
     DONE))
 
-(define-vop (fast-ash-c)
+(define-vop (fast-ash-c/signed=>signed)
   (:policy :fast-safe)
   (:translate ash)
   (:note nil)
   (:policy :fast-safe)
   (:translate ash)
   (:note nil)
-  (:args (number :scs (signed-reg unsigned-reg)))
+  (:args (number :scs (signed-reg)))
   (:info count)
   (:info count)
-  (:arg-types (:or signed-num unsigned-num) (:constant integer))
-  (:results (result :scs (signed-reg unsigned-reg)))
-  (:result-types (:or signed-num unsigned-num))
+  (:arg-types signed-num (:constant integer))
+  (:results (result :scs (signed-reg)))
+  (:result-types signed-num)
   (:generator 1
   (:generator 1
-    (cond ((< count 0)
-          ;; It is a right shift.
-          (sc-case number
-            (signed-reg (inst sra number (- count) result))
-            (unsigned-reg (inst srl number (- count) result))))
-         ((> count 0)
-          ;; It is a left shift.
-          (inst sll number count result))
-         (t
-          ;; Count=0?  Shouldn't happen, but it's easy:
-          (move number result)))))
+    (cond
+      ((< count 0) (inst sra number (min 63 (- count)) result))
+      ((> count 0) (inst sll number (min 63 count) result))
+      (t (bug "identity ASH not transformed away")))))
 
 
-(define-vop (signed-byte-32-len)
+(define-vop (fast-ash-c/unsigned=>unsigned)
+  (:policy :fast-safe)
+  (:translate ash)
+  (:note nil)
+  (:args (number :scs (unsigned-reg)))
+  (:info count)
+  (:arg-types unsigned-num (:constant integer))
+  (:results (result :scs (unsigned-reg)))
+  (:result-types unsigned-num)
+  (:generator 1
+    (cond
+      ((< count -63) (move zero-tn result))
+      ((< count 0) (inst sra number (- count) result))
+      ((> count 0) (inst sll number (min 63 count) result))
+      (t (bug "identity ASH not transformed away")))))
+
+(define-vop (signed-byte-64-len)
   (:translate integer-length)
   (:translate integer-length)
-  (:note "inline (signed-byte 32) integer-length")
+  (:note "inline (signed-byte 64) integer-length")
   (:policy :fast-safe)
   (:args (arg :scs (signed-reg) :to (:argument 1)))
   (:arg-types signed-num)
   (:policy :fast-safe)
   (:args (arg :scs (signed-reg) :to (:argument 1)))
   (:arg-types signed-num)
   (:generator 30
     (inst not arg shift)
     (inst cmovge arg arg shift)
   (:generator 30
     (inst not arg shift)
     (inst cmovge arg arg shift)
-    (inst subq zero-tn 4 res)
+    (inst subq zero-tn (fixnumize 1) res)
     (inst sll shift 1 shift)
     LOOP
     (inst addq res (fixnumize 1) res)
     (inst srl shift 1 shift)
     (inst bne shift loop)))
 
     (inst sll shift 1 shift)
     LOOP
     (inst addq res (fixnumize 1) res)
     (inst srl shift 1 shift)
     (inst bne shift loop)))
 
-(define-vop (unsigned-byte-32-count)
+(define-vop (unsigned-byte-64-count)
   (:translate logcount)
   (:translate logcount)
-  (:note "inline (unsigned-byte 32) logcount")
+  (:note "inline (unsigned-byte 64) logcount")
   (:policy :fast-safe)
   (:args (arg :scs (unsigned-reg) :target num))
   (:arg-types unsigned-num)
   (:policy :fast-safe)
   (:args (arg :scs (unsigned-reg) :target num))
   (:arg-types unsigned-num)
   (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)
                    :target res) num)
   (:temporary (:scs (non-descriptor-reg)) mask temp)
   (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)
                    :target res) num)
   (:temporary (:scs (non-descriptor-reg)) mask temp)
-  (:generator 30
-    (inst li #x55555555 mask)
+  (:generator 60
+    ;; FIXME: now this looks expensive, what with these 64bit loads.
+    ;; Maybe a loop and count would be faster?  -- CSR, 2003-09-10
+    (inst li #x5555555555555555 mask)
     (inst srl arg 1 temp)
     (inst and arg mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
     (inst srl arg 1 temp)
     (inst and arg mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
-    (inst li #x33333333 mask)
+    (inst li #x3333333333333333 mask)
     (inst srl num 2 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
     (inst srl num 2 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
-    (inst li #x0f0f0f0f mask)
+    (inst li #x0f0f0f0f0f0f0f0f mask)
     (inst srl num 4 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
     (inst srl num 4 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
-    (inst li #x00ff00ff mask)
+    (inst li #x00ff00ff00ff00ff mask)
     (inst srl num 8 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
     (inst srl num 8 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst addq num temp num)
-    (inst li #x0000ffff mask)
+    (inst li #x0000ffff0000ffff mask)
     (inst srl num 16 temp)
     (inst and num mask num)
     (inst and temp mask temp)
     (inst srl num 16 temp)
     (inst and num mask num)
     (inst and temp mask temp)
+    (inst addq num temp num)
+    (inst li #x00000000ffffffff mask)
+    (inst srl num 32 temp)
+    (inst and num mask num)
+    (inst and temp mask temp)
     (inst addq num temp res)))
     (inst addq num temp res)))
-
-
-;;; Multiply
+\f
+;;;; multiplying
 
 (define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)
   (:temporary (:scs (non-descriptor-reg)) temp)
 
 (define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)
   (:temporary (:scs (non-descriptor-reg)) temp)
   (:translate *)
   (:generator 3
     (inst mulq x y r)))
   (:translate *)
   (:generator 3
     (inst mulq x y r)))
+\f
+;;;; Modular functions:
+(define-modular-fun lognot-mod64 (x) lognot 64)
+(define-vop (lognot-mod64/unsigned=>unsigned)
+  (:translate lognot-mod64)
+  (:args (x :scs (unsigned-reg)))
+  (:arg-types unsigned-num)
+  (:results (res :scs (unsigned-reg)))
+  (:result-types unsigned-num)
+  (:policy :fast-safe)
+  (:generator 1
+    (inst not x res)))
 
 
-
+(macrolet
+    ((define-modular-backend (fun &optional constantp)
+       (let ((mfun-name (symbolicate fun '-mod64))
+             (modvop (symbolicate 'fast- fun '-mod64/unsigned=>unsigned))
+             (modcvop (symbolicate 'fast- fun 'mod64-c/unsigned=>unsigned))
+             (vop (symbolicate 'fast- fun '/unsigned=>unsigned))
+             (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned)))
+         `(progn
+            (define-modular-fun ,mfun-name (x y) ,fun 64)
+            (define-vop (,modvop ,vop)
+              (:translate ,mfun-name))
+            ,@(when constantp
+                `((define-vop (,modcvop ,cvop)
+                    (:translate ,mfun-name))))))))
+  (define-modular-backend + t)
+  (define-modular-backend logxor t)
+  (define-modular-backend logeqv t)
+  (define-modular-backend logandc1)
+  (define-modular-backend logandc2 t)
+  (define-modular-backend logorc1)
+  (define-modular-backend logorc2 t))
+
+(define-source-transform lognand (x y)
+  `(lognot (logand ,x ,y)))
+(define-source-transform lognor (x y)
+  `(lognot (logior ,x ,y)))
 \f
 \f
-;;;; Binary conditional VOPs:
+;;;; binary conditional VOPs
 
 (define-vop (fast-conditional)
   (:conditional)
 
 (define-vop (fast-conditional)
   (:conditional)
   (:temporary (:scs (non-descriptor-reg)) temp)
   (:policy :fast-safe))
 
   (:temporary (:scs (non-descriptor-reg)) temp)
   (:policy :fast-safe))
 
-(deftype integer-with-a-bite-out (s bite)
-  (cond ((eq s '*) 'integer)
-       ((and (integerp s) (> s 1))
-        (let ((bound (ash 1 s)))
-          `(integer 0 ,(- bound bite 1))))
-       (t
-        (error "Bad size specified for SIGNED-BYTE type specifier: ~S." s))))
-
 (define-vop (fast-conditional/fixnum fast-conditional)
   (:args (x :scs (any-reg))
         (y :scs (any-reg)))
 (define-vop (fast-conditional/fixnum fast-conditional)
   (:args (x :scs (any-reg))
         (y :scs (any-reg)))
 
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg)))
 
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg)))
-  (:arg-types tagged-num (:constant (integer-with-a-bite-out 6 4)))
+  (:arg-types tagged-num (:constant (unsigned-byte-with-a-bite-out 6 4)))
   (:info target not-p y))
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg))
         (y :scs (signed-reg)))
   (:arg-types signed-num signed-num)
   (:info target not-p y))
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg))
         (y :scs (signed-reg)))
   (:arg-types signed-num signed-num)
-  (:note "inline (signed-byte 32) comparison"))
+  (:note "inline (signed-byte 64) comparison"))
 
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg)))
 
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg)))
-  (:arg-types signed-num (:constant (integer-with-a-bite-out 8 1)))
+  (:arg-types signed-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
   (:info target not-p y))
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg))
         (y :scs (unsigned-reg)))
   (:arg-types unsigned-num unsigned-num)
   (:info target not-p y))
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg))
         (y :scs (unsigned-reg)))
   (:arg-types unsigned-num unsigned-num)
-  (:note "inline (unsigned-byte 32) comparison"))
+  (:note "inline (unsigned-byte 64) comparison"))
 
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg)))
 
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg)))
-  (:arg-types unsigned-num (:constant (integer-with-a-bite-out 8 1)))
+  (:arg-types unsigned-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
   (:info target not-p y))
 
 
 (defmacro define-conditional-vop (translate &rest generator)
   `(progn
   (:info target not-p y))
 
 
 (defmacro define-conditional-vop (translate &rest generator)
   `(progn
-     ,@(mapcar #'(lambda (suffix cost signed)
-                  (unless (and (member suffix '(/fixnum -c/fixnum))
-                               (eq translate 'eql))
-                    `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"
-                                                   translate suffix))
-                                  ,(intern
-                                    (format nil "~:@(FAST-CONDITIONAL~A~)"
-                                            suffix)))
-                       (:translate ,translate)
-                       (:generator ,cost
-                         (let* ((signed ,signed)
-                                (-c/fixnum ,(eq suffix '-c/fixnum))
-                                (y (if -c/fixnum (fixnumize y) y)))
-                           ,@generator)))))
+     ,@(mapcar (lambda (suffix cost signed)
+                (unless (and (member suffix '(/fixnum -c/fixnum))
+                             (eq translate 'eql))
+                  `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"
+                                                 translate suffix))
+                                ,(intern
+                                  (format nil "~:@(FAST-CONDITIONAL~A~)"
+                                          suffix)))
+                     (:translate ,translate)
+                     (:generator ,cost
+                                 (let* ((signed ,signed)
+                                        (-c/fixnum ,(eq suffix '-c/fixnum))
+                                        (y (if -c/fixnum (fixnumize y) y)))
+                                   ,@generator)))))
               '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
               '(3 2 5 4 5 4)
               '(t t t t nil nil))))
               '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
               '(3 2 5 4 5 4)
               '(t t t t nil nil))))
             (inst beq temp target)
             (inst bne temp target)))))
 
             (inst beq temp target)
             (inst bne temp target)))))
 
-;;; EQL/FIXNUM is funny because the first arg can be of any type, not just a
-;;; known fixnum.
+;;; EQL/FIXNUM is funny because the first arg can be of any type, not
+;;; just a known fixnum.
 
 (define-conditional-vop eql
   (declare (ignore signed))
 
 (define-conditional-vop eql
   (declare (ignore signed))
       (inst beq temp target)
       (inst bne temp target)))
 
       (inst beq temp target)
       (inst bne temp target)))
 
-;;; These versions specify a fixnum restriction on their first arg.  We have
-;;; also generic-eql/fixnum VOPs which are the same, but have no restriction on
-;;; the first arg and a higher cost.  The reason for doing this is to prevent
-;;; fixnum specific operations from being used on word integers, spuriously
-;;; consing the argument.
-;;;
+;;; These versions specify a fixnum restriction on their first arg. We
+;;; have also generic-eql/fixnum VOPs which are the same, but have no
+;;; restriction on the first arg and a higher cost. The reason for
+;;; doing this is to prevent fixnum specific operations from being
+;;; used on word integers, spuriously consing the argument.
 (define-vop (fast-eql/fixnum fast-conditional)
   (:args (x :scs (any-reg))
         (y :scs (any-reg)))
 (define-vop (fast-eql/fixnum fast-conditional)
   (:args (x :scs (any-reg))
         (y :scs (any-reg)))
       (emit-label done)
       (move res result))))
 
       (emit-label done)
       (move res result))))
 
+(define-source-transform 32bit-logical-not (x)
+  `(logand (lognot (the (unsigned-byte 32) ,x)) #.(1- (ash 1 32))))
 
 
-(define-vop (32bit-logical)
-  (:args (x :scs (unsigned-reg))
-        (y :scs (unsigned-reg)))
-  (:arg-types unsigned-num unsigned-num)
-  (:results (r :scs (unsigned-reg)))
-  (:result-types unsigned-num)
-  (:policy :fast-safe))
-
-(define-vop (32bit-logical-not 32bit-logical)
-  (:translate 32bit-logical-not)
-  (:args (x :scs (unsigned-reg)))
-  (:arg-types unsigned-num)
-  (:generator 2
-    (inst not x r)
-    (inst mskll r 4 r)))
-
-(define-vop (32bit-logical-and 32bit-logical)
-  (:translate 32bit-logical-and)
-  (:generator 1
-    (inst and x y r)))
-
-(deftransform 32bit-logical-nand ((x y) (* *))
-  '(32bit-logical-not (32bit-logical-and x y)))
+(deftransform 32bit-logical-and ((x y))
+  '(logand x y))
 
 
-(define-vop (32bit-logical-or 32bit-logical)
-  (:translate 32bit-logical-or)
-  (:generator 1
-    (inst bis x y r)))
+(define-source-transform 32bit-logical-nand (x y)
+  `(32bit-logical-not (32bit-logical-and ,x ,y)))
 
 
-(define-vop (32bit-logical-nor 32bit-logical)
-  (:translate 32bit-logical-nor)
-  (:generator 2
-    (inst ornot x y r)
-    (inst mskll r 4 r)))
+(deftransform 32bit-logical-or ((x y))
+  '(logior x y))
 
 
-(define-vop (32bit-logical-xor 32bit-logical)
-  (:translate 32bit-logical-xor)
-  (:generator 1
-    (inst xor x y r)))
+(define-source-transform 32bit-logical-nor (x y)
+  `(logand (lognor (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
+           #.(1- (ash 1 32))))
 
 
-(deftransform 32bit-logical-eqv ((x y) (* *))
-  '(32bit-logical-not (32bit-logical-xor x y)))
+(deftransform 32bit-logical-xor ((x y))
+  '(logxor x y))
 
 
-(deftransform 32bit-logical-andc1 ((x y) (* *))
-  '(32bit-logical-and (32bit-logical-not x) y))
+(define-source-transform 32bit-logical-eqv (x y)
+  `(logand (logeqv (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
+          #.(1- (ash 1 32))))
 
 
-(deftransform 32bit-logical-andc2 ((x y) (* *))
-  '(32bit-logical-and x (32bit-logical-not y)))
+(define-source-transform 32bit-logical-orc1 (x y)
+  `(logand (logorc1 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
+          #.(1- (ash 1 32))))
 
 
-(deftransform 32bit-logical-orc1 ((x y) (* *))
-  '(32bit-logical-or (32bit-logical-not x) y))
+(define-source-transform 32bit-logical-orc2 (x y)
+  `(logand (logorc2 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
+          #.(1- (ash 1 32))))
 
 
-(deftransform 32bit-logical-orc2 ((x y) (* *))
-  '(32bit-logical-or x (32bit-logical-not y)))
+(define-source-transform 32bit-logical-andc1 (x y)
+  `(logandc1 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y)))
 
 
+(define-source-transform 32bit-logical-andc2 (x y)
+  `(logandc2 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y)))
 
 (define-vop (shift-towards-someplace)
   (:policy :fast-safe)
 
 (define-vop (shift-towards-someplace)
   (:policy :fast-safe)
   (:generator 1
     (inst and amount #x1f temp)
     (inst sll num temp r)))
   (:generator 1
     (inst and amount #x1f temp)
     (inst sll num temp r)))
-
-
 \f
 \f
-;;;; Bignum stuff.
+;;;; bignum stuff
 
 (define-vop (bignum-length get-header-data)
   (:translate sb!bignum::%bignum-length)
 
 (define-vop (bignum-length get-header-data)
   (:translate sb!bignum::%bignum-length)
   (:translate sb!bignum::%bignum-set-length)
   (:policy :fast-safe))
 
   (:translate sb!bignum::%bignum-set-length)
   (:policy :fast-safe))
 
-(define-full-reffer bignum-ref * bignum-digits-offset other-pointer-type
+(define-full-reffer bignum-ref * bignum-digits-offset other-pointer-lowtag
   (unsigned-reg) unsigned-num sb!bignum::%bignum-ref)
 
   (unsigned-reg) unsigned-num sb!bignum::%bignum-ref)
 
-(define-full-setter bignum-set * bignum-digits-offset other-pointer-type
-  (unsigned-reg) unsigned-num sb!bignum::%bignum-set #+gengc nil)
+(define-full-setter bignum-set * bignum-digits-offset other-pointer-lowtag
+  (unsigned-reg) unsigned-num sb!bignum::%bignum-set #!+gengc nil)
 
 (define-vop (digit-0-or-plus)
   (:translate sb!bignum::%digit-0-or-plusp)
 
 (define-vop (digit-0-or-plus)
   (:translate sb!bignum::%digit-0-or-plusp)
   (:generator 6
     (inst mulq x y lo)
     (inst addq lo carry-in lo)
   (:generator 6
     (inst mulq x y lo)
     (inst addq lo carry-in lo)
-    (inst sra lo 32 hi)
+    (inst srl lo 32 hi)
     (inst mskll lo 4 lo)))
 
 
     (inst mskll lo 4 lo)))
 
 
     (inst mulq x y lo)
     (inst addq lo prev lo)
     (inst addq lo carry-in lo)
     (inst mulq x y lo)
     (inst addq lo prev lo)
     (inst addq lo carry-in lo)
-    (inst sra lo 32 hi)
+    (inst srl lo 32 hi)
     (inst mskll lo 4 lo)))
 
 (define-vop (bignum-mult)
     (inst mskll lo 4 lo)))
 
 (define-vop (bignum-mult)
   (:translate sb!bignum::%ashl)
   (:generator 1
     (inst sll digit count result)))
   (:translate sb!bignum::%ashl)
   (:generator 1
     (inst sll digit count result)))
-
 \f
 \f
-;;;; Static functions.
+;;;; static functions
 
 
-(define-static-function two-arg-gcd (x y) :translate gcd)
-(define-static-function two-arg-lcm (x y) :translate lcm)
+(define-static-fun two-arg-gcd (x y) :translate gcd)
+(define-static-fun two-arg-lcm (x y) :translate lcm)
 
 
-(define-static-function two-arg-+ (x y) :translate +)
-(define-static-function two-arg-- (x y) :translate -)
-(define-static-function two-arg-* (x y) :translate *)
-(define-static-function two-arg-/ (x y) :translate /)
+(define-static-fun two-arg-+ (x y) :translate +)
+(define-static-fun two-arg-- (x y) :translate -)
+(define-static-fun two-arg-* (x y) :translate *)
+(define-static-fun two-arg-/ (x y) :translate /)
 
 
-(define-static-function two-arg-< (x y) :translate <)
-(define-static-function two-arg-<= (x y) :translate <=)
-(define-static-function two-arg-> (x y) :translate >)
-(define-static-function two-arg->= (x y) :translate >=)
-(define-static-function two-arg-= (x y) :translate =)
-(define-static-function two-arg-/= (x y) :translate /=)
+(define-static-fun two-arg-< (x y) :translate <)
+(define-static-fun two-arg-<= (x y) :translate <=)
+(define-static-fun two-arg-> (x y) :translate >)
+(define-static-fun two-arg->= (x y) :translate >=)
+(define-static-fun two-arg-= (x y) :translate =)
+(define-static-fun two-arg-/= (x y) :translate /=)
 
 
-(define-static-function %negate (x) :translate %negate)
+(define-static-fun %negate (x) :translate %negate)
 
 
-(define-static-function two-arg-and (x y) :translate logand)
-(define-static-function two-arg-ior (x y) :translate logior)
-(define-static-function two-arg-xor (x y) :translate logxor)
+(define-static-fun two-arg-and (x y) :translate logand)
+(define-static-fun two-arg-ior (x y) :translate logior)
+(define-static-fun two-arg-xor (x y) :translate logxor)
+(define-static-fun two-arg-eqv (x y) :translate logeqv)