calls.c (expand_call): Only destroy temporaries at the end of function calls, if...
[platform/upstream/gcc.git] / gcc / combine.c
index 077483f..c9a0b3b 100644 (file)
@@ -75,9 +75,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "config.h"
 #ifdef __STDC__
-#include "gstdarg.h"
+#include <stdarg.h>
 #else
-#include "gvarargs.h"
+#include <varargs.h>
 #endif
 
 /* Must precede rtl.h for FFS.  */
@@ -399,6 +399,7 @@ static rtx expand_compound_operation  PROTO((rtx));
 static rtx expand_field_assignment  PROTO((rtx));
 static rtx make_extraction     PROTO((enum machine_mode, rtx, int, rtx, int,
                                       int, int, int));
+static rtx extract_left_shift  PROTO((rtx, int));
 static rtx make_compound_operation  PROTO((rtx, enum rtx_code));
 static int get_pos_from_mask   PROTO((unsigned HOST_WIDE_INT, int *));
 static rtx force_to_mode       PROTO((rtx, enum machine_mode,
@@ -927,14 +928,16 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
       if (GET_CODE (src) == REG
          && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
               && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest)))
-#ifdef SMALL_REGISTER_CLASSES
-             /* Don't extend the life of a hard register.  */
-             || REGNO (src) < FIRST_PSEUDO_REGISTER
-#else
+             /* Don't extend the life of a hard register unless it is
+                user variable (if we have few registers) or it can't
+                fit into the desired register (meaning something special
+                is going on).  */
              || (REGNO (src) < FIRST_PSEUDO_REGISTER
-                 && ! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src)))
+                 && (! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src))
+#ifdef SMALL_REGISTER_CLASSES
+                     || ! REG_USERVAR_P (src)
 #endif
-         ))
+                     ))))
        return 0;
     }
   else if (GET_CODE (dest) != CC0)
@@ -1038,7 +1041,8 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
    of a SET must prevent combination from occurring.
 
    On machines where SMALL_REGISTER_CLASSES is defined, we don't combine
-   if the destination of a SET is a hard register.
+   if the destination of a SET is a hard register that isn't a user
+   variable.
 
    Before doing the above check, we first try to expand a field assignment
    into a set of logical operations.
@@ -1108,14 +1112,12 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
             CALL operation.  */
          || (GET_CODE (inner_dest) == REG
              && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
+             && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
+                                       GET_MODE (inner_dest))
 #ifdef SMALL_REGISTER_CLASSES
-             && GET_CODE (src) != CALL
-#else
-             && ! HARD_REGNO_MODE_OK (REGNO (inner_dest),
-                                      GET_MODE (inner_dest))
+                || (GET_CODE (src) != CALL && ! REG_USERVAR_P (inner_dest))
 #endif
-             )
-
+                 ))
          || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
        return 0;
 
@@ -1216,6 +1218,17 @@ try_combine (i3, i2, i1)
       || find_reg_note (i3, REG_LIBCALL, NULL_RTX))
     return 0;
 
+  /* If I1 or I2 is an argument set insn, and I3 is the actual
+     CALL_INSN using it as argument, never combine the two.
+     This to prevent the elimination of insns that setup a
+     parameter register for a CALL_INSN.  */
+  if (GET_CODE (i3) == CALL_INSN
+      && (((temp = single_set (i2))
+            && find_reg_fusage (i3, USE, SET_DEST (temp)))
+         || (i1 && (temp = single_set (i1))
+              && find_reg_fusage (i3, USE, SET_DEST (temp)))))
+    return 0;
+
   combine_attempts++;
 
   undobuf.num_undo = previous_num_undos = 0;
@@ -1254,7 +1267,8 @@ try_combine (i3, i2, i1)
       && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
 #ifdef SMALL_REGISTER_CLASSES
       && (GET_CODE (SET_DEST (PATTERN (i3))) != REG
-         || REGNO (SET_DEST (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER)
+         || REGNO (SET_DEST (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
+         || REG_USERVAR_P (SET_DEST (PATTERN (i3))))
 #endif
       && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
       && GET_CODE (PATTERN (i2)) == PARALLEL
@@ -2006,7 +2020,6 @@ try_combine (i3, i2, i1)
   /* If we had to change another insn, make sure it is valid also.  */
   if (undobuf.other_insn)
     {
-      rtx other_notes = REG_NOTES (undobuf.other_insn);
       rtx other_pat = PATTERN (undobuf.other_insn);
       rtx new_other_notes;
       rtx note, next;
@@ -2056,8 +2069,6 @@ try_combine (i3, i2, i1)
     rtx i3notes, i2notes, i1notes = 0;
     rtx i3links, i2links, i1links = 0;
     rtx midnotes = 0;
-    int all_adjacent = (next_real_insn (i2) == i3
-                       && (i1 == 0 || next_real_insn (i1) == i2));
     register int regno;
     /* Compute which registers we expect to eliminate.  */
     rtx elim_i2 = (newi2pat || i2dest_in_i2src || i2dest_in_i1src
@@ -2743,7 +2754,7 @@ subst (x, from, to, in_dest, unique_copy)
      int in_dest;
      int unique_copy;
 {
-  register enum rtx_code code = GET_CODE (x), orig_code = code;
+  register enum rtx_code code = GET_CODE (x);
   enum machine_mode op0_mode = VOIDmode;
   register char *fmt;
   register int len, i;
@@ -3261,16 +3272,10 @@ simplify_rtx (x, op0_mode, last, in_dest)
          && GET_MODE_SIZE (mode) > GET_MODE_SIZE (op0_mode))
        return SUBREG_REG (x);
 
-      /* If we are narrowing an integral object, we need to see if we can
-        simplify the expression for the object knowing that we only need the
-        low-order bits.  */
+      /* Note that we cannot do any narrowing for non-constants since
+        we might have been counting on using the fact that some bits were
+        zero.  We now do this in the SET.  */
 
-      if (GET_MODE_CLASS (mode) == MODE_INT
-         && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
-         && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
-         && subreg_lowpart_p (x))
-       return force_to_mode (SUBREG_REG (x), mode, GET_MODE_MASK (mode),
-                             NULL_RTX, 0);
       break;
 
     case NOT:
@@ -3627,24 +3632,6 @@ simplify_rtx (x, op0_mode, last, in_dest)
          if (GET_CODE (x) != MULT)
            return x;
        }
-
-      /* If this is multiplication by a power of two and its first operand is
-        a shift, treat the multiply as a shift to allow the shifts to
-        possibly combine.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-         && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
-         && (GET_CODE (XEXP (x, 0)) == ASHIFT
-             || GET_CODE (XEXP (x, 0)) == LSHIFTRT
-             || GET_CODE (XEXP (x, 0)) == ASHIFTRT
-             || GET_CODE (XEXP (x, 0)) == ROTATE
-             || GET_CODE (XEXP (x, 0)) == ROTATERT))
-       return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0), i);
-
-      /* Convert (mult (ashift (const_int 1) A) B) to (ashift B A).  */
-      if (GET_CODE (XEXP (x, 0)) == ASHIFT
-         && XEXP (XEXP (x, 0), 0) == const1_rtx)
-       return gen_rtx_combine (ASHIFT, mode, XEXP (x, 1),
-                               XEXP (XEXP (x, 0), 1));
       break;
 
     case UDIV:
@@ -3859,7 +3846,6 @@ simplify_rtx (x, op0_mode, last, in_dest)
        SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
       break;
 
-    case LSHIFT:
     case ASHIFT:
     case LSHIFTRT:
     case ASHIFTRT:
@@ -4059,7 +4045,7 @@ simplify_if_then_else (x)
       rtx cond_op1 = XEXP (cond, 1);
       enum rtx_code op, extend_op = NIL;
       enum machine_mode m = mode;
-      rtx z = 0, c1, c2;
+      rtx z = 0, c1;
 
       if (f == const0_rtx)
        return gen_binary (MULT, mode, gen_binary (true_code, mode, cond_op0,
@@ -4203,6 +4189,13 @@ simplify_set (x)
   if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN)
     return src;
 
+  /* Now that we know for sure which bits of SRC we are using, see if we can
+     simplify the expression for the object knowing that we only need the
+     low-order bits.  */
+
+  if (GET_MODE_CLASS (mode) == MODE_INT)
+    src = force_to_mode (src, mode, GET_MODE_MASK (mode), NULL_RTX, 0);
+
   /* Convert this into a field assignment operation, if possible.  */
   x = make_field_assignment (x);
 
@@ -4614,6 +4607,28 @@ simplify_logical (x, last)
                        (GET_CODE (op0) == ASHIFT
                         ? XEXP (op0, 1) : XEXP (op1, 1)));
 
+      /* If OP0 is (ashiftrt (plus ...) C), it might actually be
+        a (sign_extend (plus ...)).  If so, OP1 is a CONST_INT, and the PLUS
+        does not affect any of the bits in OP1, it can really be done
+        as a PLUS and we can associate.  We do this by seeing if OP1
+        can be safely shifted left C bits.  */
+      if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
+         && GET_CODE (XEXP (op0, 0)) == PLUS
+         && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
+         && GET_CODE (XEXP (op0, 1)) == CONST_INT
+         && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
+       {
+         int count = INTVAL (XEXP (op0, 1));
+         HOST_WIDE_INT mask = INTVAL (op1) << count;
+
+         if (mask >> count == INTVAL (op1)
+             && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
+           {
+             SUBST (XEXP (XEXP (op0, 0), 1),
+                    GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask));
+             return op0;
+           }
+       }
       break;
 
     case XOR:
@@ -5252,6 +5267,51 @@ make_extraction (mode, inner, pos, pos_rtx, len,
   return new;
 }
 \f
+/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
+   with any other operations in X.  Return X without that shift if so.  */
+
+static rtx
+extract_left_shift (x, count)
+     rtx x;
+     int count;
+{
+  enum rtx_code code = GET_CODE (x);
+  enum machine_mode mode = GET_MODE (x);
+  rtx tem;
+
+  switch (code)
+    {
+    case ASHIFT:
+      /* This is the shift itself.  If it is wide enough, we will return
+        either the value being shifted if the shift count is equal to
+        COUNT or a shift for the difference.  */
+      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+         && INTVAL (XEXP (x, 1)) >= count)
+       return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
+                                    INTVAL (XEXP (x, 1)) - count);
+      break;
+
+    case NEG:  case NOT:
+      if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
+       return gen_unary (code, mode, tem);
+
+      break;
+
+    case PLUS:  case IOR:  case XOR:  case AND:
+      /* If we can safely shift this constant and we find the inner shift,
+        make a new operation.  */
+      if (GET_CODE (XEXP (x,1)) == CONST_INT
+         && (INTVAL (XEXP (x, 1)) & (((HOST_WIDE_INT) 1 << count)) - 1) == 0
+         && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
+       return gen_binary (code, mode, tem, 
+                          GEN_INT (INTVAL (XEXP (x, 1)) >> count));
+
+      break;
+    }
+
+  return 0;
+}
+\f
 /* Look at the expression rooted at X.  Look for expressions
    equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND.
    Form these expressions.
@@ -5278,8 +5338,9 @@ make_compound_operation (x, in_code)
   enum rtx_code code = GET_CODE (x);
   enum machine_mode mode = GET_MODE (x);
   int mode_width = GET_MODE_BITSIZE (mode);
+  rtx rhs, lhs;
   enum rtx_code next_code;
-  int i, count;
+  int i;
   rtx new = 0;
   rtx tem;
   char *fmt;
@@ -5299,7 +5360,6 @@ make_compound_operation (x, in_code)
   switch (code)
     {
     case ASHIFT:
-    case LSHIFT:
       /* Convert shifts by constants into multiplications if inside
         an address.  */
       if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
@@ -5341,7 +5401,7 @@ make_compound_operation (x, in_code)
                                 XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
                                 0, in_code == COMPARE);
        }
-      /* Same as previous, but for (xor/ior (lshift...) (lshift...)).  */
+      /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)).  */
       else if ((GET_CODE (XEXP (x, 0)) == XOR
                || GET_CODE (XEXP (x, 0)) == IOR)
               && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
@@ -5434,81 +5494,38 @@ make_compound_operation (x, in_code)
       /* ... fall through ... */
 
     case ASHIFTRT:
+      lhs = XEXP (x, 0);
+      rhs = XEXP (x, 1);
+
       /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
         this is a SIGN_EXTRACT.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-         && GET_CODE (XEXP (x, 0)) == ASHIFT
-         && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-         && INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (x, 0), 1)))
+      if (GET_CODE (rhs) == CONST_INT
+         && GET_CODE (lhs) == ASHIFT
+         && GET_CODE (XEXP (lhs, 1)) == CONST_INT
+         && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
        {
-         new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
+         new = make_compound_operation (XEXP (lhs, 0), next_code);
          new = make_extraction (mode, new,
-                                (INTVAL (XEXP (x, 1))
-                                 - INTVAL (XEXP (XEXP (x, 0), 1))),
-                                NULL_RTX, mode_width - INTVAL (XEXP (x, 1)),
+                                INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
+                                NULL_RTX, mode_width - INTVAL (rhs),
                                 code == LSHIFTRT, 0, in_code == COMPARE);
        }
 
-      /* Similarly if we have (ashifrt (OP (ashift foo C1) C3) C2).  In these
-        cases, we are better off returning a SIGN_EXTEND of the operation.  */
-
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-         && (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND
-             || GET_CODE (XEXP (x, 0)) == XOR
-             || GET_CODE (XEXP (x, 0)) == PLUS)
-         && GET_CODE (XEXP (XEXP (x, 0), 0)) == ASHIFT
-         && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
-         && INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)) < HOST_BITS_PER_WIDE_INT
-         && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-         && 0 == (INTVAL (XEXP (XEXP (x, 0), 1))
-                  & (((HOST_WIDE_INT) 1
-                      << (MIN (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)),
-                               INTVAL (XEXP (x, 1)))
-                          - 1)))))
-       {
-         rtx c1 = XEXP (XEXP (XEXP (x, 0), 0), 1);
-         rtx c2 = XEXP (x, 1);
-         rtx c3 = XEXP (XEXP (x, 0), 1);
-         HOST_WIDE_INT newop1;
-         rtx inner = XEXP (XEXP (XEXP (x, 0), 0), 0);
-
-         /* If C1 > C2, INNER needs to have the shift performed on it
-            for C1-C2 bits.  */
-         if (INTVAL (c1) > INTVAL (c2))
-           {
-             inner = gen_binary (ASHIFT, mode, inner,
-                                 GEN_INT (INTVAL (c1) - INTVAL (c2)));
-             c1 = c2;
-           }
-
-         newop1 = INTVAL (c3) >> INTVAL (c1);
-         new = make_compound_operation (inner,
-                                        GET_CODE (XEXP (x, 0)) == PLUS
-                                        ? MEM : GET_CODE (XEXP (x, 0)));
-         new = make_extraction (mode,
-                                gen_binary (GET_CODE (XEXP (x, 0)), mode, new,
-                                            GEN_INT (newop1)),
-                                INTVAL (c2) - INTVAL (c1),
-                                NULL_RTX, mode_width - INTVAL (c2),
-                                code == LSHIFTRT, 0, in_code == COMPARE);
-       }
-
-      /* Similarly for (ashiftrt (neg (ashift FOO C1)) C2).  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-         && GET_CODE (XEXP (x, 0)) == NEG
-         && GET_CODE (XEXP (XEXP (x, 0), 0)) == ASHIFT
-         && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
-         && INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
-       {
-         new = make_compound_operation (XEXP (XEXP (XEXP (x, 0), 0), 0),
-                                        next_code);
-         new = make_extraction (mode,
-                                gen_unary (GET_CODE (XEXP (x, 0)), mode, new),
-                                (INTVAL (XEXP (x, 1))
-                                 - INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))),
-                                NULL_RTX, mode_width - INTVAL (XEXP (x, 1)),
-                                code == LSHIFTRT, 0, in_code == COMPARE);
-       }
+      /* See if we have operations between an ASHIFTRT and an ASHIFT.
+        If so, try to merge the shifts into a SIGN_EXTEND.  We could
+        also do this for some cases of SIGN_EXTRACT, but it doesn't
+        seem worth the effort; the case checked for occurs on Alpha.  */
+      
+      if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o'
+         && ! (GET_CODE (lhs) == SUBREG
+               && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o'))
+         && GET_CODE (rhs) == CONST_INT
+         && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
+         && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
+       new = make_extraction (mode, make_compound_operation (new, next_code),
+                              0, NULL_RTX, mode_width - INTVAL (rhs),
+                              code == LSHIFTRT, 0, in_code == COMPARE);
+       
       break;
 
     case SUBREG:
@@ -5664,9 +5681,9 @@ force_to_mode (x, mode, mask, reg, just_select)
   if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
     return gen_lowpart_for_combine (mode, x);
 
-  /* If we aren't changing the mode and all zero bits in MASK are already
-     known to be zero in X, we need not do anything.  */
-  if (GET_MODE (x) == mode && (~ mask & nonzero) == 0)
+  /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in
+     MASK are already known to be zero in X, we need not do anything.  */
+  if (GET_MODE (x) == mode && code != SUBREG && (~ mask & nonzero) == 0)
     return x;
 
   switch (code)
@@ -5729,13 +5746,37 @@ force_to_mode (x, mode, mask, reg, just_select)
                                      mask & INTVAL (XEXP (x, 1)));
 
          /* If X is still an AND, see if it is an AND with a mask that
-            is just some low-order bits.  If so, and it is BITS wide (it
-            can't be wider), we don't need it.  */
+            is just some low-order bits.  If so, and it is MASK, we don't
+            need it.  */
 
          if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
              && INTVAL (XEXP (x, 1)) == mask)
            x = XEXP (x, 0);
 
+         /* If it remains an AND, try making another AND with the bits
+            in the mode mask that aren't in MASK turned on.  If the
+            constant in the AND is wide enough, this might make a
+            cheaper constant.  */
+
+         if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
+             && GET_MODE_MASK (GET_MODE (x)) != mask)
+           {
+             HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1))
+                                   | (GET_MODE_MASK (GET_MODE (x)) & ~ mask));
+             int width = GET_MODE_BITSIZE (GET_MODE (x));
+             rtx y;
+
+             /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
+                number, sign extend it.  */
+             if (width > 0 && width < HOST_BITS_PER_WIDE_INT
+                 && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
+               cval |= (HOST_WIDE_INT) -1 << width;
+
+             y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
+             if (rtx_cost (y, SET) < rtx_cost (x, SET))
+               x = y;
+           }
+
          break;
        }
 
@@ -5814,7 +5855,6 @@ force_to_mode (x, mode, mask, reg, just_select)
       break;
 
     case ASHIFT:
-    case LSHIFT:
       /* For left shifts, do the same, but just for the first operand.
         However, we cannot do anything with shifts where we cannot
         guarantee that the counts are smaller than the size of the mode
@@ -5961,7 +6001,7 @@ force_to_mode (x, mode, mask, reg, just_select)
          temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
                                            GET_MODE (x), GEN_INT (mask),
                                            XEXP (x, 1));
-         if (temp)
+         if (temp && GET_CODE(temp) == CONST_INT)
            SUBST (XEXP (x, 0),
                   force_to_mode (XEXP (x, 0), GET_MODE (x),
                                  INTVAL (temp), reg, next_select));
@@ -6218,7 +6258,7 @@ known_cond (x, cond, reg, val)
      rtx reg, val;
 {
   enum rtx_code code = GET_CODE (x);
-  rtx new, temp;
+  rtx temp;
   char *fmt;
   int i, j;
 
@@ -6304,7 +6344,6 @@ make_field_assignment (x)
 {
   rtx dest = SET_DEST (x);
   rtx src = SET_SRC (x);
-  rtx ourdest;
   rtx assign;
   HOST_WIDE_INT c1;
   int pos, len;
@@ -6462,8 +6501,7 @@ apply_distributive_law (x)
       break;
 
     case ASHIFT:
-    case LSHIFT:
-      /* These are also multiplies, so they distribute over everything.  */
+      /* This is also a multiply, so it distributes over everything.  */
       break;
 
     case SUBREG:
@@ -6545,8 +6583,6 @@ simplify_and_const_int (x, mode, varop, constop)
      rtx varop;
      unsigned HOST_WIDE_INT constop;
 {
-  register enum machine_mode tmode;
-  register rtx temp;
   unsigned HOST_WIDE_INT nonzero;
   int i;
 
@@ -6932,7 +6968,6 @@ nonzero_bits (x, mode)
     case ASHIFTRT:
     case LSHIFTRT:
     case ASHIFT:
-    case LSHIFT:
     case ROTATE:
       /* The nonzero bits are in two classes: any bits within MODE
         that aren't in GET_MODE (x) are always significant.  The rest of the
@@ -6967,7 +7002,7 @@ nonzero_bits (x, mode)
              if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
                inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
            }
-         else if (code == LSHIFT || code == ASHIFT)
+         else if (code == ASHIFT)
            inner <<= count;
          else
            inner = ((inner << (count % width)
@@ -7235,7 +7270,6 @@ num_sign_bit_copies (x, mode)
       return num0;
 
     case ASHIFT:
-    case LSHIFT:
       /* Left shifts destroy copies.  */
       if (GET_CODE (XEXP (x, 1)) != CONST_INT
          || INTVAL (XEXP (x, 1)) < 0
@@ -7483,10 +7517,6 @@ simplify_shift_const (x, code, result_mode, varop, count)
       if (code == ROTATERT)
        code = ROTATE, count = GET_MODE_BITSIZE (result_mode) - count;
 
-      /* Canonicalize LSHIFT to ASHIFT.  */
-      if (code == LSHIFT)
-       code = ASHIFT;
-
       /* We need to determine what mode we will do the shift in.  If the
         shift is a ASHIFTRT or ROTATE, we must always do it in the mode it
         was originally done in.  Otherwise, we can do it in MODE, the widest
@@ -7678,7 +7708,6 @@ simplify_shift_const (x, code, result_mode, varop, count)
 
        case LSHIFTRT:
        case ASHIFT:
-       case LSHIFT:
        case ROTATE:
          /* Here we have two nested shifts.  The result is usually the
             AND of a new shift with a mask.  We compute the result below.  */
@@ -7692,10 +7721,6 @@ simplify_shift_const (x, code, result_mode, varop, count)
              int first_count = INTVAL (XEXP (varop, 1));
              unsigned HOST_WIDE_INT mask;
              rtx mask_rtx;
-             rtx inner;
-
-             if (first_code == LSHIFT)
-               first_code = ASHIFT;
 
              /* We have one common special case.  We can't do any merging if
                 the inner code is an ASHIFTRT of a smaller mode.  However, if
@@ -7876,6 +7901,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
              && (new = simplify_binary_operation (code, result_mode,
                                                   XEXP (varop, 1),
                                                   GEN_INT (count))) != 0
+             && GET_CODE(new) == CONST_INT
              && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
                                  INTVAL (new), result_mode, &complement_p))
            {
@@ -7900,11 +7926,11 @@ simplify_shift_const (x, code, result_mode, varop, count)
          break;
 
        case EQ:
-         /* convert (lshift (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
+         /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
             says that the sign bit can be tested, FOO has mode MODE, C is
-            GET_MODE_BITSIZE (MODE) - 1, and FOO has only the low-order bit
-            may be nonzero.  */
-         if (code == LSHIFT
+            GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit
+            that may be nonzero.  */
+         if (code == LSHIFTRT
              && XEXP (varop, 1) == const0_rtx
              && GET_MODE (XEXP (varop, 0)) == result_mode
              && count == GET_MODE_BITSIZE (result_mode) - 1
@@ -7995,6 +8021,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
              && (new = simplify_binary_operation (ASHIFT, result_mode,
                                                   XEXP (varop, 1),
                                                   GEN_INT (count))) != 0
+             && GET_CODE(new) == CONST_INT
              && merge_outer_ops (&outer_op, &outer_const, PLUS,
                                  INTVAL (new), result_mode, &complement_p))
            {
@@ -8522,9 +8549,7 @@ simplify_comparison (code, pop0, pop1)
       if (GET_CODE (op0) == GET_CODE (op1)
          && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
          && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
-             || ((GET_CODE (op0) == LSHIFTRT
-                  || GET_CODE (op0) == ASHIFT
-                  || GET_CODE (op0) == LSHIFT)
+             || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
                  && (code != GT && code != LT && code != GE && code != LE))
              || (GET_CODE (op0) == ASHIFTRT
                  && (code != GTU && code != LTU
@@ -8540,7 +8565,7 @@ simplify_comparison (code, pop0, pop1)
 
          if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
            mask &= (mask >> shift_count) << shift_count;
-         else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFT)
+         else if (GET_CODE (op0) == ASHIFT)
            mask = (mask & (mask << shift_count)) >> shift_count;
 
          if ((nonzero_bits (XEXP (op0, 0), mode) & ~ mask) == 0
@@ -9150,8 +9175,7 @@ simplify_comparison (code, pop0, pop1)
          /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1).  This
             will be converted to a ZERO_EXTRACT later.  */
          if (const_op == 0 && equality_comparison_p
-             && (GET_CODE (XEXP (op0, 0)) == ASHIFT
-                 || GET_CODE (XEXP (op0, 0)) == LSHIFT)
+             && GET_CODE (XEXP (op0, 0)) == ASHIFT
              && XEXP (XEXP (op0, 0), 0) == const1_rtx)
            {
              op0 = simplify_and_const_int
@@ -9218,8 +9242,7 @@ simplify_comparison (code, pop0, pop1)
          break;
 
        case ASHIFT:
-       case LSHIFT:
-         /* If we have (compare (xshift FOO N) (const_int C)) and
+         /* If we have (compare (ashift FOO N) (const_int C)) and
             the high order N bits of FOO (N+1 if an inequality comparison)
             are known to be zero, we can do this by comparing FOO with C
             shifted right N bits so long as the low-order N bits of C are
@@ -10132,7 +10155,7 @@ move_deaths (x, from_cuid, to_insn, pnotes)
                if (i < regno || i >= ourend)
                  REG_NOTES (where_dead)
                    = gen_rtx (EXPR_LIST, REG_DEAD,
-                              gen_rtx (REG, word_mode, i),
+                              gen_rtx (REG, reg_raw_mode[i], i),
                               REG_NOTES (where_dead));
            }
 
@@ -10411,7 +10434,11 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
             In both cases, we must search to see if we can find a previous
             use of A and put the death note there.  */
 
-         if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
+         if (from_insn
+             && GET_CODE (from_insn) == CALL_INSN
+              && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
+           place = from_insn;
+         else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
            place = i3;
          else if (i2 != 0 && next_nonnote_insn (i2) == i3
                   && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
@@ -10685,6 +10712,12 @@ distribute_links (links)
              place = insn;
            break;
          }
+       else if (GET_CODE (insn) == CALL_INSN
+             && find_reg_fusage (insn, USE, reg))
+         {
+           place = insn;
+           break;
+         }
 
       /* If we found a place to put the link, place it there unless there
         is already a link to the same insn as LINK at that point.  */