OSDN Git Service

*** empty log message ***
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jul 1992 09:52:19 +0000 (09:52 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jul 1992 09:52:19 +0000 (09:52 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@1611 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/combine.c
gcc/reload.c

index ba100ad..b3865ed 100644 (file)
@@ -3182,49 +3182,6 @@ subst (x, from, to, in_dest, unique_copy)
       /* Convert this into a field assignment operation, if possible.  */
       x = make_field_assignment (x);
 
-      /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some
-        operation, and X being a REG or (subreg (reg)), we may be able to
-        convert this to (set (subreg:m2 x) (op)).
-
-        We can always do this if M1 is narrower than M2 because that
-        means that we only care about the low bits of the result.
-
-        However, on most machines (those with BYTE_LOADS_ZERO_EXTEND
-        not defined), we cannot perform a narrower operation that
-        requested since the high-order bits will be undefined.  On
-        machine where BYTE_LOADS_ZERO_EXTEND are defined, however, this
-        transformation is safe as long as M1 and M2 have the same number
-        of words.  */
-      if (GET_CODE (SET_SRC (x)) == SUBREG
-         && subreg_lowpart_p (SET_SRC (x))
-         && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) != 'o'
-         && (((GET_MODE_SIZE (GET_MODE (SET_SRC (x))) + (UNITS_PER_WORD - 1))
-              / UNITS_PER_WORD)
-             == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))
-                  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
-#ifndef BYTE_LOADS_ZERO_EXTEND
-         && (GET_MODE_SIZE (GET_MODE (SET_SRC (x)))
-             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))))
-#endif
-         && (GET_CODE (SET_DEST (x)) == REG
-             || (GET_CODE (SET_DEST (x)) == SUBREG
-                 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG)))
-       {
-         /* Get the object that will be the SUBREG_REG of the
-            SUBREG we are making.  Note that SUBREG_WORD will always
-            be zero because this will either be a paradoxical SUBREG
-            or a SUBREG with the same number of words on the outside and
-            inside.  */
-         rtx object = (GET_CODE (SET_DEST (x)) == REG ? SET_DEST (x)
-                       : SUBREG_REG (SET_DEST (x)));
-
-         SUBST (SET_DEST (x),
-                gen_rtx (SUBREG, GET_MODE (SUBREG_REG (SET_SRC (x))),
-                         object, 0));
-         SUBST (SET_SRC (x), SUBREG_REG (SET_SRC (x)));
-       }
-
       /* If we are setting CC0 or if the source is a COMPARE, look for the
         use of the comparison result and try to simplify it unless we already
         have used undobuf.other_insn.  */
@@ -3356,6 +3313,49 @@ subst (x, from, to, in_dest, unique_copy)
          SUBST (SET_SRC (x), temp);
        }
 
+      /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some
+        operation, and X being a REG or (subreg (reg)), we may be able to
+        convert this to (set (subreg:m2 x) (op)).
+
+        We can always do this if M1 is narrower than M2 because that
+        means that we only care about the low bits of the result.
+
+        However, on most machines (those with BYTE_LOADS_ZERO_EXTEND
+        not defined), we cannot perform a narrower operation that
+        requested since the high-order bits will be undefined.  On
+        machine where BYTE_LOADS_ZERO_EXTEND are defined, however, this
+        transformation is safe as long as M1 and M2 have the same number
+        of words.  */
+      if (GET_CODE (SET_SRC (x)) == SUBREG
+         && subreg_lowpart_p (SET_SRC (x))
+         && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) != 'o'
+         && (((GET_MODE_SIZE (GET_MODE (SET_SRC (x))) + (UNITS_PER_WORD - 1))
+              / UNITS_PER_WORD)
+             == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))
+                  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
+#ifndef BYTE_LOADS_ZERO_EXTEND
+         && (GET_MODE_SIZE (GET_MODE (SET_SRC (x)))
+             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))))
+#endif
+         && (GET_CODE (SET_DEST (x)) == REG
+             || (GET_CODE (SET_DEST (x)) == SUBREG
+                 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG)))
+       {
+         /* Get the object that will be the SUBREG_REG of the
+            SUBREG we are making.  Note that SUBREG_WORD will always
+            be zero because this will either be a paradoxical SUBREG
+            or a SUBREG with the same number of words on the outside and
+            inside.  */
+         rtx object = (GET_CODE (SET_DEST (x)) == REG ? SET_DEST (x)
+                       : SUBREG_REG (SET_DEST (x)));
+
+         SUBST (SET_DEST (x),
+                gen_rtx (SUBREG, GET_MODE (SUBREG_REG (SET_SRC (x))),
+                         object, 0));
+         SUBST (SET_SRC (x), SUBREG_REG (SET_SRC (x)));
+       }
+
 #ifdef BYTE_LOADS_ZERO_EXTEND
       /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with
         M wider than N, this would require a paradoxical subreg.
@@ -4029,10 +4029,11 @@ make_extraction (mode, inner, pos, pos_rtx, len,
 
   if (tmode != BLKmode
       && ! (spans_byte && inner_mode != tmode)
-      && ((pos == 0 && GET_CODE (inner) == REG
+      && ((pos == 0 && GET_CODE (inner) != MEM
           && (! in_dest
-              || (movstrict_optab->handlers[(int) tmode].insn_code
-                  != CODE_FOR_nothing)))
+              || (GET_CODE (inner) == REG
+                  && (movstrict_optab->handlers[(int) tmode].insn_code
+                      != CODE_FOR_nothing))))
          || (GET_CODE (inner) == MEM && pos >= 0
              && (pos
                  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
@@ -4051,7 +4052,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
         adjust the offset.  Otherwise, we do if bytes big endian.  
 
         If INNER is not a MEM, get a piece consisting of the just the field
-        of interest (in this case INNER must be a REG and POS must be 0).  */
+        of interest (in this case POS must be 0).  */
 
       if (GET_CODE (inner) == MEM)
        {
@@ -4066,7 +4067,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
          MEM_VOLATILE_P (new) = MEM_VOLATILE_P (inner);
          MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (inner);
        }
-      else if (GET_MODE (inner) == REG)
+      else if (GET_CODE (inner) == REG)
        /* We can't call gen_lowpart_for_combine here since we always want
           a SUBREG and it would sometimes return a new hard register.  */
        new = gen_rtx (SUBREG, tmode, inner,
@@ -4417,7 +4418,7 @@ make_compound_operation (x, in_code)
 
   if (new)
     {
-      x = new;
+      x = gen_lowpart_for_combine (mode, new);
       code = GET_CODE (x);
     }
 
index b6bcbb2..62f8d67 100644 (file)
@@ -476,7 +476,10 @@ push_reload (in, out, inloc, outloc, class,
      we can't handle it here because CONST_INT does not indicate a mode.
 
      Similarly, we must reload the inside expression if we have a
-     STRICT_LOW_PART (presumably, in == out in the cas).  */
+     STRICT_LOW_PART (presumably, in == out in the cas).
+
+     Also reload the inner expression if it does not require a secondary
+     reload but the SUBREG does.  */
 
   if (in != 0 && GET_CODE (in) == SUBREG
       && (GET_CODE (SUBREG_REG (in)) != REG
@@ -494,7 +497,15 @@ push_reload (in, out, inloc, outloc, class,
                      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                           / UNITS_PER_WORD)
                          != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
-                                              GET_MODE (SUBREG_REG (in)))))))))
+                                              GET_MODE (SUBREG_REG (in)))))))
+#ifdef SECONDARY_INPUT_RELOAD_CLASS
+         || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
+             && (SECONDARY_INPUT_RELOAD_CLASS (class,
+                                               GET_MODE (SUBREG_REG (in)),
+                                               SUBREG_REG (in))
+                 == NO_REGS))
+#endif
+         ))
     {
       in_subreg_loc = inloc;
       inloc = &SUBREG_REG (in);
@@ -529,7 +540,15 @@ push_reload (in, out, inloc, outloc, class,
                      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
                           / UNITS_PER_WORD)
                          != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
-                                              GET_MODE (SUBREG_REG (out)))))))))
+                                              GET_MODE (SUBREG_REG (out)))))))
+#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
+         || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
+             && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
+                                                GET_MODE (SUBREG_REG (out)),
+                                                SUBREG_REG (out))
+                 == NO_REGS))
+#endif
+         ))
     {
       out_subreg_loc = outloc;
       outloc = &SUBREG_REG (out);