]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that boiled down to && ! 0.
authorRichard Henderson <rth@cygnus.com>
Mon, 20 Apr 1998 01:22:13 +0000 (18:22 -0700)
committerJeff Law <law@gcc.gnu.org>
Mon, 20 Apr 1998 01:22:13 +0000 (19:22 -0600)
        * reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
        boiled down to && ! 0.
        * reload.c (find_reloads): Always force (subreg (mem)) to be
        reloaded if WORD_REGISTER_OPERATIONS.
        * reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
        SUBREGs of CONST_INTs.
        * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
        SUBREG_REG if the word count is unchanged, also in the input reload
        case.  Disable non-applicable sanity checks.
        * reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
        to require the SUBREG mode to be smaller than the SUBREG_REG mode.
        * reload1.c (eliminate_regs): Likewise.
        * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
        SUBREG_REG if the word count is unchanged.
        * reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
        subregs of identical word size for push_reload.
Various alpha fixes from the mainline sources.

Co-Authored-By: J"orn Rennecke <amylaar@cygnus.co.uk>
Co-Authored-By: Jim Wilson <wilson@cygnus.com>
From-SVN: r19336

gcc/ChangeLog
gcc/reload.c
gcc/reload1.c

index e1ca3cf3e5b065a98cec0fc28333767c6a9e0fef..4b5c39d1b515068fec0a5a5b9446ab7102066d7f 100644 (file)
@@ -1,3 +1,29 @@
+Mon Apr 20 02:17:37 1998  Richard Henderson  <rth@cygnus.com>               
+                         Jim Wilson  <wilson@cygnus.com>
+                         J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
+       boiled down to && ! 0.                                         
+
+       * reload.c (find_reloads): Always force (subreg (mem)) to be
+       reloaded if WORD_REGISTER_OPERATIONS.
+
+       * reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical    
+       SUBREGs of CONST_INTs.                                         
+
+       * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the 
+       SUBREG_REG if the word count is unchanged, also in the input reload   
+       case.  Disable non-applicable sanity checks.
+
+       * reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
+       to require the SUBREG mode to be smaller than the SUBREG_REG mode.
+       * reload1.c (eliminate_regs): Likewise.                               
+        
+       * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
+       SUBREG_REG if the word count is unchanged.           
+       * reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
+       subregs of identical word size for push_reload.                 
+
 Mon Apr 20 00:58:48 1998  H.J. Lu  (hjl@gnu.org)
 
        * reg-stack.c (subst_asm_stack_regs): Change to return the last
index 4b48a6c317128f392ffe175d90c1dc9c7fafd785..a979550d793c88a1abeea6c52140a98ea6828209 100644 (file)
@@ -889,6 +889,13 @@ push_reload (in, out, inloc, outloc, class,
                          > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
                      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
                      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
+#endif
+#ifdef WORD_REGISTER_OPERATIONS
+                 || ((GET_MODE_SIZE (inmode)
+                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+                     && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
+                         ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
+                          / UNITS_PER_WORD)))
 #endif
                  ))
          || (GET_CODE (SUBREG_REG (in)) == REG
@@ -927,7 +934,7 @@ push_reload (in, out, inloc, outloc, class,
       in_subreg_loc = inloc;
       inloc = &SUBREG_REG (in);
       in = *inloc;
-#ifndef LOAD_EXTEND_OP
+#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
       if (GET_CODE (in) == MEM)
        /* This is supposed to happen only for paradoxical subregs made by
           combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
@@ -989,7 +996,15 @@ push_reload (in, out, inloc, outloc, class,
                && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
               || GET_CODE (SUBREG_REG (out)) == MEM)
              && ((GET_MODE_SIZE (outmode)
-                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
+                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+#ifdef WORD_REGISTER_OPERATIONS
+                 || ((GET_MODE_SIZE (outmode)
+                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+                     && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
+                         ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
+                          / UNITS_PER_WORD)))
+#endif
+                 ))
          || (GET_CODE (SUBREG_REG (out)) == REG
              && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
              && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
@@ -1023,7 +1038,7 @@ push_reload (in, out, inloc, outloc, class,
       out_subreg_loc = outloc;
       outloc = &SUBREG_REG (out);
       out = *outloc; 
-#ifndef LOAD_EXTEND_OP
+#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
      if (GET_CODE (out) == MEM
          && GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
        abort ();
@@ -2757,10 +2772,20 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                     register access.  If the data is, in fact, in memory we
                     must always load using the size assumed to be in the
                     register and let the insn do the different-sized 
-                    accesses.  */
+                    accesses.
+
+                    This is doubly true if WORD_REGISTER_OPERATIONS.  In 
+                    this case eliminate_regs has left non-paradoxical
+                    subregs for push_reloads to see.  Make sure it does
+                    by forcing the reload.
+
+                    ??? When is it right at this stage to have a subreg
+                    of a mem that is _not_ to be handled specialy?  IMO
+                    those should have been reduced to just a mem.  */
                  || ((GET_CODE (operand) == MEM
                       || (GET_CODE (operand)== REG
                           && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
+#ifndef WORD_REGISTER_OPERATIONS
                      && (((GET_MODE_BITSIZE (GET_MODE (operand))
                            < BIGGEST_ALIGNMENT)
                           && (GET_MODE_SIZE (operand_mode[i])
@@ -2775,7 +2800,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                              && INTEGRAL_MODE_P (GET_MODE (operand))
                              && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
 #endif
-                         ))
+                         )
+#endif
+                     )
                  /* Subreg of a hard reg which can't handle the subreg's mode
                     or which would handle that mode in the wrong number of
                     registers for subregging to work.  */
@@ -4162,6 +4189,29 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
                                     GET_MODE (SUBREG_REG (x)))) != 0)
        return tem;
 
+      /* If the SUBREG is wider than a word, the above test will fail.
+        For example, we might have a SImode SUBREG of a DImode SUBREG_REG
+        for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
+        a 32 bit target.  We still can - and have to - handle this
+        for non-paradoxical subregs of CONST_INTs.  */
+      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
+         && reg_equiv_constant[regno] != 0
+         && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
+         && (GET_MODE_SIZE (GET_MODE (x))
+             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+         {
+           int shift = SUBREG_WORD (x) * BITS_PER_WORD;
+           if (WORDS_BIG_ENDIAN)
+             shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
+                      - GET_MODE_BITSIZE (GET_MODE (x))
+                      - shift);
+           /* Here we use the knowledge that CONST_INTs have a
+              HOST_WIDE_INT field.  */
+           if (shift >= HOST_BITS_PER_WIDE_INT)
+             shift = HOST_BITS_PER_WIDE_INT - 1;
+           return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
+         }
+
       if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
          && reg_equiv_constant[regno] != 0
          && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
index cbb41308ddb30ce3b38aad78b09ecd43529840c1..565ba4b7802f9888fbd6359003abd64266be152f 100644 (file)
@@ -3108,30 +3108,21 @@ eliminate_regs (x, mem_mode, insn, storing)
          int x_size = GET_MODE_SIZE (GET_MODE (x));
          int new_size = GET_MODE_SIZE (GET_MODE (new));
 
-         /* When asked to spill a partial word subreg, we need to go
-            ahead and spill the whole thing against the possibility
-            that we reload the whole reg and find garbage at the top.  */
-         if (storing
-             && GET_CODE (new) == MEM
-             && x_size < new_size
-             && ((x_size + UNITS_PER_WORD-1) / UNITS_PER_WORD
-                 == (new_size + UNITS_PER_WORD-1) / UNITS_PER_WORD))
-           return new;
-         else if (GET_CODE (new) == MEM
-                  && x_size <= new_size
-#ifdef LOAD_EXTEND_OP
-                  /* On these machines we will be reloading what is
-                     inside the SUBREG if it originally was a pseudo and
-                     the inner and outer modes are both a word or
-                     smaller.  So leave the SUBREG then.  */
-                  && ! (GET_CODE (SUBREG_REG (x)) == REG
-                        && x_size <= UNITS_PER_WORD
-                        && new_size <= UNITS_PER_WORD
-                        && x_size > new_size
-                        && INTEGRAL_MODE_P (GET_MODE (new))
-                        && LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
+         if (GET_CODE (new) == MEM
+             && ((x_size < new_size
+#ifdef WORD_REGISTER_OPERATIONS
+                  /* On these machines, combine can create rtl of the form
+                     (set (subreg:m1 (reg:m2 R) 0) ...)
+                     where m1 < m2, and expects something interesting to 
+                     happen to the entire word.  Moreover, it will use the
+                     (reg:m2 R) later, expecting all bits to be preserved.
+                     So if the number of words is the same, preserve the 
+                     subreg so that push_reloads can see it.  */
+                  && ! ((x_size-1)/UNITS_PER_WORD == (new_size-1)/UNITS_PER_WORD)
 #endif
-                  )
+                  )
+                 || (x_size == new_size))
+             )
            {
              int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
              enum machine_mode mode = GET_MODE (x);
@@ -3271,12 +3262,6 @@ eliminate_regs (x, mem_mode, insn, storing)
            && GET_CODE (insn) != INSN_LIST)
          emit_insn_after (gen_rtx (CLOBBER, VOIDmode, SET_DEST (x)), insn);
 
-       /* If SET_DEST was a partial-word subreg, NEW0 may have been widened
-          to spill the entire register (see SUBREG case above).  If the 
-          widths of SET_DEST and NEW0 no longer match, adjust NEW1.  */
-       if (GET_MODE (SET_DEST (x)) != GET_MODE (new0))
-         new1 = gen_rtx (SUBREG, GET_MODE (new0), new1, 0);
-
        if (new0 != SET_DEST (x) || new1 != SET_SRC (x))
          return gen_rtx (SET, VOIDmode, new0, new1);
       }