OSDN Git Service

* gcc.c-torture/execute/ieee/ieee.exp: Change sh-*-* to sh*-*-*.
[pf3gnuchains/gcc-fork.git] / gcc / regclass.c
index 9d1fe55..826da24 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1991, 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 two passes of the compiler: reg_scan and reg_class.
@@ -74,7 +74,7 @@ HARD_REG_SET fixed_reg_set;
 
 /* Data for initializing the above.  */
 
-static char initial_fixed_regs[] = FIXED_REGISTERS;
+static const char initial_fixed_regs[] = FIXED_REGISTERS;
 
 /* Indexed by hard register number, contains 1 for registers
    that are fixed use or are clobbered by function calls.
@@ -93,18 +93,15 @@ HARD_REG_SET losing_caller_save_reg_set;
 
 /* Data for initializing the above.  */
 
-static char initial_call_used_regs[] = CALL_USED_REGISTERS;
+static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
 
 /* This is much like call_used_regs, except it doesn't have to
    be a superset of FIXED_REGISTERS. This vector indicates
    what is really call clobbered, and is used when defining 
    regs_invalidated_by_call.  */
 
-char call_really_used_regs[] = 
 #ifdef CALL_REALLY_USED_REGISTERS
-                               CALL_REALLY_USED_REGISTERS;
-#else
-                               CALL_USED_REGISTERS;
+char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
 #endif
   
 /* Indexed by hard register number, contains 1 for registers that are
@@ -268,7 +265,7 @@ struct reg_info_data {
 static struct reg_info_data *reg_info_head;
 
 /* No more global register variables may be declared; true once
-   regclass has been initialized. */
+   regclass has been initialized.  */
 
 static int no_global_reg_vars = 0;
 
@@ -279,7 +276,7 @@ static int no_global_reg_vars = 0;
 void
 init_reg_sets ()
 {
-  register int i, j;
+  int i, j;
 
   /* First copy the register information from the initial int form into
      the regsets.  */
@@ -314,8 +311,8 @@ init_reg_sets ()
 static void
 init_reg_sets_1 ()
 {
-  register unsigned int i, j;
-  register unsigned int /* enum machine_mode */ m;
+  unsigned int i, j;
+  unsigned int /* enum machine_mode */ m;
   char allocatable_regs_of_mode [MAX_MACHINE_MODE];
 
   /* This macro allows the fixed or call-used registers
@@ -345,7 +342,7 @@ init_reg_sets_1 ()
          register              /* Declare it register if it's a scalar.  */
 #endif
            HARD_REG_SET c;
-         register int k;
+         int k;
 
          COPY_HARD_REG_SET (c, reg_class_contents[i]);
          IOR_HARD_REG_SET (c, reg_class_contents[j]);
@@ -379,7 +376,7 @@ init_reg_sets_1 ()
          register              /* Declare it register if it's a scalar.  */
 #endif
            HARD_REG_SET c;
-         register int k;
+         int k;
 
          COPY_HARD_REG_SET (c, reg_class_contents[i]);
          IOR_HARD_REG_SET (c, reg_class_contents[j]);
@@ -476,7 +473,13 @@ init_reg_sets_1 ()
       else if (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
        ;
 #endif
-      else if (call_really_used_regs[i] || global_regs[i])
+      else if (0
+#ifdef CALL_REALLY_USED_REGISTERS
+              || call_really_used_regs[i]
+#else
+              || call_used_regs[i]
+#endif
+              || global_regs[i])
        SET_HARD_REG_BIT (regs_invalidated_by_call, i);
     }
 
@@ -515,7 +518,7 @@ init_reg_sets_1 ()
                  }
                else
                  {
-                   cost = i == j ? 2 : REGISTER_MOVE_COST (m, i, j);
+                   cost = REGISTER_MOVE_COST (m, i, j);
 
                    for (p2 = &reg_class_subclasses[j][0];
                         *p2 != LIM_REG_CLASSES;
@@ -575,7 +578,7 @@ init_reg_sets_1 ()
 static void
 init_reg_modes ()
 {
-  register int i;
+  int i;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
@@ -630,7 +633,7 @@ memory_move_secondary_cost (mode, class, in)
   enum reg_class altclass;
   int partial_cost = 0;
   /* We need a memory reference to feed to SECONDARY... macros.  */
-  /* mem may be unused even if the SECONDARY_ macros are defined. */
+  /* mem may be unused even if the SECONDARY_ macros are defined.  */
   rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
 
 
@@ -759,8 +762,10 @@ fix_register (name, fixed, call_used)
        {
          fixed_regs[i] = fixed;
          call_used_regs[i] = call_used;
+#ifdef CALL_REALLY_USED_REGISTERS
          if (fixed == 0)
            call_really_used_regs[i] = call_used;
+#endif
        }
     }
   else
@@ -843,7 +848,7 @@ static struct costs init_cost;
 
 static struct reg_pref *reg_pref;
 
-/* Allocated buffers for reg_pref. */
+/* Allocated buffers for reg_pref.  */
 
 static struct reg_pref *reg_pref_buffer;
 
@@ -903,7 +908,7 @@ regclass_init ()
      before regclass is run.  */
   reg_pref = NULL;
 
-  /* No more global register variables may be declared. */
+  /* No more global register variables may be declared.  */
   no_global_reg_vars = 1;
 }
 \f
@@ -1158,8 +1163,8 @@ regclass (f, nregs, dump)
      int nregs;
      FILE *dump;
 {
-  register rtx insn;
-  register int i;
+  rtx insn;
+  int i;
   int pass;
 
   init_recog ();
@@ -1183,7 +1188,7 @@ regclass (f, nregs, dump)
     {
       rtx r = gen_rtx_REG (VOIDmode, 0);
       enum machine_mode m;
-      register int j;
+      int j;
 
       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
        if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
@@ -1284,12 +1289,12 @@ regclass (f, nregs, dump)
        }
       for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
        {
-         register int best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
+         int best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
          enum reg_class best = ALL_REGS, alt = NO_REGS;
          /* This is an enum reg_class, but we call it an int
             to save lots of casts.  */
-         register int class;
-         register struct costs *p = &costs[i];
+         int class;
+         struct costs *p = &costs[i];
 
          /* In non-optimizing compilation REG_N_REFS is not initialized
             yet.  */
@@ -1299,7 +1304,7 @@ regclass (f, nregs, dump)
          for (class = (int) ALL_REGS - 1; class > 0; class--)
            {
              /* Ignore classes that are too small for this operand or
-                invalid for a operand that was auto-incremented.  */
+                invalid for an operand that was auto-incremented.  */
              if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
 #ifdef FORBIDDEN_INC_DEC_CLASSES
                  || (in_inc_dec[i] && forbidden_inc_dec_class[class])
@@ -1943,7 +1948,7 @@ record_address_regs (x, class, scale)
      enum reg_class class;
      int scale;
 {
-  register enum rtx_code code = GET_CODE (x);
+  enum rtx_code code = GET_CODE (x);
 
   switch (code)
     {
@@ -1971,8 +1976,8 @@ record_address_regs (x, class, scale)
       {
        rtx arg0 = XEXP (x, 0);
        rtx arg1 = XEXP (x, 1);
-       register enum rtx_code code0 = GET_CODE (arg0);
-       register enum rtx_code code1 = GET_CODE (arg1);
+       enum rtx_code code0 = GET_CODE (arg0);
+       enum rtx_code code1 = GET_CODE (arg1);
 
        /* Look inside subregs.  */
        if (code0 == SUBREG)
@@ -2092,8 +2097,8 @@ record_address_regs (x, class, scale)
 
     case REG:
       {
-       register struct costs *pp = &costs[REGNO (x)];
-       register int i;
+       struct costs *pp = &costs[REGNO (x)];
+       int i;
 
        pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
 
@@ -2104,8 +2109,8 @@ record_address_regs (x, class, scale)
 
     default:
       {
-       register const char *fmt = GET_RTX_FORMAT (code);
-       register int i;
+       const char *fmt = GET_RTX_FORMAT (code);
+       int i;
        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
          if (fmt[i] == 'e')
            record_address_regs (XEXP (x, i), class, scale);
@@ -2313,7 +2318,7 @@ reg_scan (f, nregs, repeat)
      unsigned int nregs;
      int repeat ATTRIBUTE_UNUSED;
 {
-  register rtx insn;
+  rtx insn;
 
   allocate_reg_info (nregs, TRUE, FALSE);
   max_parallel = 3;
@@ -2347,7 +2352,7 @@ reg_scan_update (first, last, old_max_regno)
      rtx last;
      unsigned int old_max_regno;
 {
-  register rtx insn;
+  rtx insn;
 
   allocate_reg_info (max_reg_num (), FALSE, FALSE);
 
@@ -2378,9 +2383,9 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
      int note_flag;
      unsigned int min_regno;
 {
-  register enum rtx_code code;
-  register rtx dest;
-  register rtx note;
+  enum rtx_code code;
+  rtx dest;
+  rtx note;
 
   code = GET_CODE (x);
   switch (code)
@@ -2491,19 +2496,37 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
                      || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
        REG_POINTER (SET_DEST (x)) = 1;
 
+      /* If this is setting a register from a register or from a simple
+        conversion of a register, propagate REG_DECL.  */
+      if (GET_CODE (dest) == REG)
+       {
+         rtx src = SET_SRC (x);
+
+         while (GET_CODE (src) == SIGN_EXTEND
+                || GET_CODE (src) == ZERO_EXTEND
+                || GET_CODE (src) == TRUNCATE
+                || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
+           src = XEXP (src, 0);
+
+         if (GET_CODE (src) == REG && REGNO_DECL (REGNO (src)) == 0)
+           REGNO_DECL (REGNO (src)) = REGNO_DECL (REGNO (dest));
+         else if (GET_CODE (src) == REG && REGNO_DECL (REGNO (dest)) == 0)
+           REGNO_DECL (REGNO (dest)) = REGNO_DECL (REGNO (src));
+       }
+
       /* ... fall through ...  */
 
     default:
       {
-       register const char *fmt = GET_RTX_FORMAT (code);
-       register int i;
+       const char *fmt = GET_RTX_FORMAT (code);
+       int i;
        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
          {
            if (fmt[i] == 'e')
              reg_scan_mark_refs (XEXP (x, i), insn, note_flag, min_regno);
            else if (fmt[i] == 'E' && XVEC (x, i) != 0)
              {
-               register int j;
+               int j;
                for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                  reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag, min_regno);
              }
@@ -2517,8 +2540,8 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
 
 int
 reg_class_subset_p (c1, c2)
-     register enum reg_class c1;
-     register enum reg_class c2;
+     enum reg_class c1;
+     enum reg_class c2;
 {
   if (c1 == c2) return 1;
 
@@ -2535,8 +2558,8 @@ reg_class_subset_p (c1, c2)
 
 int
 reg_classes_intersect_p (c1, c2)
-     register enum reg_class c1;
-     register enum reg_class c2;
+     enum reg_class c1;
+     enum reg_class c2;
 {
 #ifdef HARD_REG_SET
   register