OSDN Git Service

* simplify-rtx.c (simplify_binary_operation): Revert last change.
[pf3gnuchains/gcc-fork.git] / gcc / reload.c
index a569ab8..b069d18 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /* This file contains subroutines used only from the file reload1.c.
    It knows how to scan one insn for operands and values
@@ -91,6 +91,8 @@ a register with any other reload.  */
 #include "rtl.h"
 #include "tm_p.h"
 #include "insn-config.h"
+#include "expr.h"
+#include "optabs.h"
 #include "recog.h"
 #include "reload.h"
 #include "regs.h"
@@ -99,7 +101,6 @@ a register with any other reload.  */
 #include "real.h"
 #include "output.h"
 #include "function.h"
-#include "expr.h"
 #include "toplev.h"
 
 #ifndef REGISTER_MOVE_COST
@@ -241,9 +242,6 @@ static int push_secondary_reload PARAMS ((int, rtx, int, int, enum reg_class,
 #endif
 static enum reg_class find_valid_class PARAMS ((enum machine_mode, int));
 static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode));
-static int push_reload         PARAMS ((rtx, rtx, rtx *, rtx *, enum reg_class,
-                                      enum machine_mode, enum machine_mode,
-                                      int, int, int, enum reload_type));
 static void push_replacement   PARAMS ((rtx *, int, enum machine_mode));
 static void combine_reloads    PARAMS ((void));
 static int find_reusable_reload        PARAMS ((rtx *, rtx, enum reg_class,
@@ -844,7 +842,7 @@ reload_inner_reg_of_subreg (x, mode)
    the two reload-numbers are equal, but the caller should be careful to
    distinguish them.  */
 
-static int
+int
 push_reload (in, out, inloc, outloc, class,
             inmode, outmode, strict_low, optional, opnum, type)
      rtx in, out;
@@ -3874,7 +3872,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
          if (GET_CODE (insn) != JUMP_INSN
              && GET_CODE (substitution) == LABEL_REF
              && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
-           REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
+           REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
                                                  XEXP (substitution, 0),
                                                  REG_NOTES (insn));
        }
@@ -4418,30 +4416,6 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
        x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
                                         insn);
     }
-  else if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM
-          && (GET_MODE_SIZE (GET_MODE (x))
-              > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-          && mode_dependent_address_p (XEXP (SUBREG_REG (x), 0)))
-    {
-      /* A paradoxical subreg will simply have the mode of the access
-        changed, so we need to reload such a memory operand to stabilize
-        the meaning of the memory access.  */
-      enum machine_mode subreg_mode = GET_MODE (SUBREG_REG (x));
-
-      /* SUBREG_REG (x) is a MEM, so we cant take the offset, instead we 
-         calculate the register number as : 
-        SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode) */
-      if (is_set_dest)
-       push_reload (NULL_RTX, SUBREG_REG (x), (rtx*)0, &SUBREG_REG (x),
-                    find_valid_class (subreg_mode, 
-                               SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode)),
-                    VOIDmode, subreg_mode, 0, 0, opnum, type);
-      else
-       push_reload (SUBREG_REG (x), NULL_RTX, &SUBREG_REG (x), (rtx*)0,
-                    find_valid_class (subreg_mode,
-                               SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode)),
-                    subreg_mode, VOIDmode, 0, 0, opnum, type);
-    }
 
   for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
@@ -4485,7 +4459,13 @@ make_memloc (ad, regno)
     tem = copy_rtx (tem);
 
   tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
-  return adjust_address_nv (tem, GET_MODE (ad), 0);
+  tem = adjust_address_nv (tem, GET_MODE (ad), 0);
+
+  /* Copy the result if it's still the same as the equivalence, to avoid
+     modifying it when we do the substitution for the reload.  */
+  if (tem == reg_equiv_memory_loc[regno])
+    tem = copy_rtx (tem);
+  return tem;
 }
 
 /* Record all reloads needed for handling memory address AD
@@ -5768,12 +5748,38 @@ subst_reloads (insn)
       register rtx reloadreg = rld[r->what].reg_rtx;
       if (reloadreg)
        {
+#ifdef ENABLE_CHECKING
+         /* Internal consistency test.  Check that we don't modify
+            anything in the equivalence arrays.  Whenever something from
+            those arrays needs to be reloaded, it must be unshared before
+            being substituted into; the equivalence must not be modified.
+            Otherwise, if the equivalence is used after that, it will
+            have been modified, and the thing substituted (probably a
+            register) is likely overwritten and not a usable equivalence.  */
+         int check_regno;
+
+         for (check_regno = 0; check_regno < max_regno; check_regno++)
+           {
+#define CHECK_MODF(ARRAY)                                              \
+             if (ARRAY[check_regno]                                    \
+                 && loc_mentioned_in_p (r->where,                      \
+                                        ARRAY[check_regno]))           \
+               abort ()
+
+             CHECK_MODF (reg_equiv_constant);
+             CHECK_MODF (reg_equiv_memory_loc);
+             CHECK_MODF (reg_equiv_address);
+             CHECK_MODF (reg_equiv_mem);
+#undef CHECK_MODF
+           }
+#endif /* ENABLE_CHECKING */
+
          /* If we're replacing a LABEL_REF with a register, add a
             REG_LABEL note to indicate to flow which label this
             register refers to.  */
          if (GET_CODE (*r->where) == LABEL_REF
              && GET_CODE (insn) == JUMP_INSN)
-           REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
+           REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
                                                  XEXP (*r->where, 0),
                                                  REG_NOTES (insn));