0.8.3.56:
[sbcl.git] / src / compiler / srctran.lisp
index f675b2e..f6caaae 100644 (file)
              ;; They must both be positive.
              (cond ((or (null x-len) (null y-len))
                     (specifier-type 'unsigned-byte))
-                   ((or (zerop x-len) (zerop y-len))
-                    (specifier-type '(integer 0 0)))
                    (t
-                    (specifier-type `(unsigned-byte ,(min x-len y-len)))))
+                    (specifier-type `(unsigned-byte* ,(min x-len y-len)))))
              ;; X is positive, but Y might be negative.
              (cond ((null x-len)
                     (specifier-type 'unsigned-byte))
-                   ((zerop x-len)
-                    (specifier-type '(integer 0 0)))
                    (t
-                    (specifier-type `(unsigned-byte ,x-len)))))
+                    (specifier-type `(unsigned-byte* ,x-len)))))
          ;; X might be negative.
          (if (not y-neg)
              ;; Y must be positive.
              (cond ((null y-len)
                     (specifier-type 'unsigned-byte))
-                   ((zerop y-len)
-                    (specifier-type '(integer 0 0)))
-                   (t
-                    (specifier-type
-                     `(unsigned-byte ,y-len))))
+                   (t (specifier-type `(unsigned-byte* ,y-len))))
              ;; Either might be negative.
              (if (and x-len y-len)
                  ;; The result is bounded.
       (cond
        ((and (not x-neg) (not y-neg))
        ;; Both are positive.
-       (if (and x-len y-len (zerop x-len) (zerop y-len))
-           (specifier-type '(integer 0 0))
-           (specifier-type `(unsigned-byte ,(if (and x-len y-len)
-                                            (max x-len y-len)
-                                            '*)))))
+       (specifier-type `(unsigned-byte* ,(if (and x-len y-len)
+                                             (max x-len y-len)
+                                             '*))))
        ((not x-pos)
        ;; X must be negative.
        (if (not y-pos)
            (and (not x-pos) (not y-pos)))
        ;; Either both are negative or both are positive. The result
        ;; will be positive, and as long as the longer.
-       (if (and x-len y-len (zerop x-len) (zerop y-len))
-           (specifier-type '(integer 0 0))
-           (specifier-type `(unsigned-byte ,(if (and x-len y-len)
-                                            (max x-len y-len)
-                                            '*)))))
+       (specifier-type `(unsigned-byte* ,(if (and x-len y-len)
+                                             (max x-len y-len)
+                                             '*))))
        ((or (and (not x-pos) (not y-neg))
            (and (not y-neg) (not y-pos)))
        ;; Either X is negative and Y is positive of vice-versa. The
             (csubtypep size (specifier-type 'integer)))
        (let ((size-high (numeric-type-high size)))
          (if (and size-high (<= size-high sb!vm:n-word-bits))
-             (specifier-type `(unsigned-byte ,size-high))
+             (specifier-type `(unsigned-byte* ,size-high))
              (specifier-type 'unsigned-byte)))
        *universal-type*)))
 
              (posn-high (numeric-type-high posn)))
          (if (and size-high posn-high
                   (<= (+ size-high posn-high) sb!vm:n-word-bits))
-             (specifier-type `(unsigned-byte ,(+ size-high posn-high)))
+             (specifier-type `(unsigned-byte* ,(+ size-high posn-high)))
              (specifier-type 'unsigned-byte)))
        *universal-type*)))
 
-(defoptimizer (%dpb derive-type) ((newbyte size posn int))
+(defun %deposit-field-derive-type-aux (size posn int)
   (let ((size (continuation-type size))
        (posn (continuation-type posn))
        (int (continuation-type int)))
-    (if (and (numeric-type-p size)
-            (csubtypep size (specifier-type 'integer))
-            (numeric-type-p posn)
-            (csubtypep posn (specifier-type 'integer))
-            (numeric-type-p int)
-            (csubtypep int (specifier-type 'integer)))
-       (let ((size-high (numeric-type-high size))
-             (posn-high (numeric-type-high posn))
-             (high (numeric-type-high int))
-             (low (numeric-type-low int)))
-         (if (and size-high posn-high high low
-                  (<= (+ size-high posn-high) sb!vm:n-word-bits))
-             (specifier-type
-              (list (if (minusp low) 'signed-byte 'unsigned-byte)
-                    (max (integer-length high)
-                         (integer-length low)
-                         (+ size-high posn-high))))
-             *universal-type*))
-       *universal-type*)))
+    (when (and (numeric-type-p size)
+               (numeric-type-p posn)
+               (numeric-type-p int))
+      (let ((size-high (numeric-type-high size))
+            (posn-high (numeric-type-high posn))
+            (high (numeric-type-high int))
+            (low (numeric-type-low int)))
+        (when (and size-high posn-high high low
+                  ;; KLUDGE: we need this cutoff here, otherwise we
+                  ;; will merrily derive the type of %DPB as
+                  ;; (UNSIGNED-BYTE 1073741822), and then attempt to
+                  ;; canonicalize this type to (INTEGER 0 (1- (ASH 1
+                  ;; 1073741822))), with hilarious consequences.  We
+                  ;; cutoff at 4*SB!VM:N-WORD-BITS to allow inference
+                  ;; over a reasonable amount of shifting, even on
+                  ;; the alpha/32 port, where N-WORD-BITS is 32 but
+                  ;; machine integers are 64-bits.  -- CSR,
+                  ;; 2003-09-12
+                   (<= (+ size-high posn-high) (* 4 sb!vm:n-word-bits)))
+          (let ((raw-bit-count (max (integer-length high)
+                                    (integer-length low)
+                                    (+ size-high posn-high))))
+            (specifier-type
+             (if (minusp low)
+                 `(signed-byte ,(1+ raw-bit-count))
+                 `(unsigned-byte* ,raw-bit-count)))))))))
+
+(defoptimizer (%dpb derive-type) ((newbyte size posn int))
+  (%deposit-field-derive-type-aux size posn int))
 
 (defoptimizer (%deposit-field derive-type) ((newbyte size posn int))
-  (let ((size (continuation-type size))
-       (posn (continuation-type posn))
-       (int (continuation-type int)))
-    (if (and (numeric-type-p size)
-            (csubtypep size (specifier-type 'integer))
-            (numeric-type-p posn)
-            (csubtypep posn (specifier-type 'integer))
-            (numeric-type-p int)
-            (csubtypep int (specifier-type 'integer)))
-       (let ((size-high (numeric-type-high size))
-             (posn-high (numeric-type-high posn))
-             (high (numeric-type-high int))
-             (low (numeric-type-low int)))
-         (if (and size-high posn-high high low
-                  (<= (+ size-high posn-high) sb!vm:n-word-bits))
-             (specifier-type
-              (list (if (minusp low) 'signed-byte 'unsigned-byte)
-                    (max (integer-length high)
-                         (integer-length low)
-                         (+ size-high posn-high))))
-             *universal-type*))
-       *universal-type*)))
+  (%deposit-field-derive-type-aux size posn int))
 
 (deftransform %ldb ((size posn int)
                    (fixnum fixnum integer)