OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / genattrtab.c
index fcf449c..1c916b3 100644 (file)
@@ -1,24 +1,24 @@
 /* Generate code from machine description to compute values of attributes.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2002 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
-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 program handles insn attributes and the DEFINE_DELAY and
    DEFINE_FUNCTION_UNIT definitions.
@@ -231,7 +231,7 @@ struct function_unit
   struct function_unit_op *ops;        /* Pointer to first operation type.  */
   int needs_conflict_function; /* Nonzero if a conflict function required.  */
   int needs_blockage_function; /* Nonzero if a blockage function required.  */
-  int needs_range_function;    /* Nonzero if blockage range function needed.*/
+  int needs_range_function;    /* Nonzero if blockage range function needed.  */
   rtx default_cost;            /* Conflict cost, if constant.  */
   struct range issue_delay;    /* Range of issue delay values.  */
   int max_blockage;            /* Maximum time an insn blocks the unit.  */
@@ -365,7 +365,8 @@ rtx pic_offset_table_rtx;
 static void attr_hash_add_rtx  PARAMS ((int, rtx));
 static void attr_hash_add_string PARAMS ((int, char *));
 static rtx attr_rtx            PARAMS ((enum rtx_code, ...));
-static char *attr_printf       PARAMS ((int, const char *, ...))
+static rtx attr_rtx_1          PARAMS ((enum rtx_code, va_list));
+static char *attr_printf       PARAMS ((unsigned int, const char *, ...))
   ATTRIBUTE_PRINTF_2;
 static char *attr_string        PARAMS ((const char *, int));
 static rtx check_attr_test     PARAMS ((rtx, int, int));
@@ -417,6 +418,7 @@ static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
 static rtx simplify_and_tree   PARAMS ((rtx, rtx *, int, int));
 static rtx simplify_or_tree    PARAMS ((rtx, rtx *, int, int));
 static rtx simplify_test_exp   PARAMS ((rtx, int, int));
+static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
 static void optimize_attrs     PARAMS ((void));
 static void gen_attr           PARAMS ((rtx, int));
 static int count_alternatives  PARAMS ((rtx));
@@ -502,7 +504,7 @@ attr_hash_add_rtx (hashcode, rtl)
      int hashcode;
      rtx rtl;
 {
-  register struct attr_hash *h;
+  struct attr_hash *h;
 
   h = (struct attr_hash *) obstack_alloc (hash_obstack,
                                          sizeof (struct attr_hash));
@@ -519,7 +521,7 @@ attr_hash_add_string (hashcode, str)
      int hashcode;
      char *str;
 {
-  register struct attr_hash *h;
+  struct attr_hash *h;
 
   h = (struct attr_hash *) obstack_alloc (hash_obstack,
                                          sizeof (struct attr_hash));
@@ -540,25 +542,15 @@ attr_hash_add_string (hashcode, str)
    rtx attr_rtx (code, [element1, ..., elementn])  */
 
 static rtx
-attr_rtx VPARAMS ((enum rtx_code code, ...))
+attr_rtx_1 (code, p)
+     enum rtx_code code;
+     va_list p;
 {
-#ifndef ANSI_PROTOTYPES
-  enum rtx_code code;
-#endif
-  va_list p;
-  register int i;              /* Array indices...                     */
-  register const char *fmt;    /* Current rtx's format...              */
-  register rtx rt_val = NULL_RTX;/* RTX to return to caller...         */
+  rtx rt_val = NULL_RTX;/* RTX to return to caller...          */
   int hashcode;
-  register struct attr_hash *h;
+  struct attr_hash *h;
   struct obstack *old_obstack = rtl_obstack;
 
-  VA_START (p, code);
-
-#ifndef ANSI_PROTOTYPES
-  code = va_arg (p, enum rtx_code);
-#endif
-
   /* For each of several cases, search the hash table for an existing entry.
      Use that entry if one is found; otherwise create a new RTL and add it
      to the table.  */
@@ -572,7 +564,6 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
        {
          rt_val = rtx_alloc (code);
          XEXP (rt_val, 0) = arg0;
-         va_end (p);
          return rt_val;
        }
 
@@ -581,7 +572,7 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
        if (h->hashcode == hashcode
            && GET_CODE (h->u.rtl) == code
            && XEXP (h->u.rtl, 0) == arg0)
-         goto found;
+         return h->u.rtl;
 
       if (h == 0)
        {
@@ -603,7 +594,6 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
          rt_val = rtx_alloc (code);
          XEXP (rt_val, 0) = arg0;
          XEXP (rt_val, 1) = arg1;
-         va_end (p);
          return rt_val;
        }
 
@@ -613,7 +603,7 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
            && GET_CODE (h->u.rtl) == code
            && XEXP (h->u.rtl, 0) == arg0
            && XEXP (h->u.rtl, 1) == arg1)
-         goto found;
+         return h->u.rtl;
 
       if (h == 0)
        {
@@ -636,7 +626,7 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
        if (h->hashcode == hashcode
            && GET_CODE (h->u.rtl) == code
            && XSTR (h->u.rtl, 0) == arg0)
-         goto found;
+         return h->u.rtl;
 
       if (h == 0)
        {
@@ -658,7 +648,7 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
            && GET_CODE (h->u.rtl) == code
            && XSTR (h->u.rtl, 0) == arg0
            && XSTR (h->u.rtl, 1) == arg1)
-         goto found;
+         return h->u.rtl;
 
       if (h == 0)
        {
@@ -672,19 +662,16 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
     {
       HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
       if (arg0 == 0)
-       {
-         va_end (p);
-         return false_rtx;
-       }
-      if (arg0 == 1)
-       {
-         va_end (p);
-         return true_rtx;
-       }
-      goto nohash;
+       return false_rtx;
+      else if (arg0 == 1)
+       return true_rtx;
+      else
+       goto nohash;
     }
   else
     {
+      int i;           /* Array indices...                     */
+      const char *fmt; /* Current rtx's format...              */
     nohash:
       rt_val = rtx_alloc (code);       /* Allocate the storage space.  */
 
@@ -721,19 +708,25 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
              abort ();
            }
        }
-      va_end (p);
       return rt_val;
     }
 
   rtl_obstack = old_obstack;
-  va_end (p);
   attr_hash_add_rtx (hashcode, rt_val);
   RTX_INTEGRATED_P (rt_val) = 1;
   return rt_val;
+}
 
- found:
-  va_end (p);
-  return h->u.rtl;
+static rtx
+attr_rtx VPARAMS ((enum rtx_code code, ...))
+{
+  rtx result;
+  
+  VA_OPEN (p, code);
+  VA_FIXEDARG (p, enum rtx_code, code);
+  result = attr_rtx_1 (code, p);
+  VA_CLOSE (p);
+  return result;
 }
 
 /* Create a new string printed with the printf line arguments into a space
@@ -742,27 +735,19 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
    rtx attr_printf (len, format, [arg1, ..., argn])  */
 
 static char *
-attr_printf VPARAMS ((register int len, const char *fmt, ...))
+attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  register int len;
-  const char *fmt;
-#endif
-  va_list p;
   char str[256];
 
-  VA_START (p, fmt);
-
-#ifndef ANSI_PROTOTYPES
-  len = va_arg (p, int);
-  fmt = va_arg (p, const char *);
-#endif
-
-  if (len > 255) /* leave room for \0 */
+  VA_OPEN (p, fmt);
+  VA_FIXEDARG (p, unsigned int, len);
+  VA_FIXEDARG (p, const char *, fmt);
+  
+  if (len > sizeof str - 1) /* Leave room for \0.  */
     abort ();
 
   vsprintf (str, fmt, p);
-  va_end (p);
+  VA_CLOSE (p);
 
   return attr_string (str, strlen (str));
 }
@@ -790,10 +775,10 @@ attr_string (str, len)
      const char *str;
      int len;
 {
-  register struct attr_hash *h;
+  struct attr_hash *h;
   int hashcode;
   int i;
-  register char *new_str;
+  char *new_str;
 
   /* Compute the hash code.  */
   hashcode = (len + 1) * 613 + (unsigned) str[0];
@@ -835,12 +820,12 @@ attr_equal_p (x, y)
 
 static rtx
 attr_copy_rtx (orig)
-     register rtx orig;
+     rtx orig;
 {
-  register rtx copy;
-  register int i, j;
-  register RTX_CODE code;
-  register const char *format_ptr;
+  rtx copy;
+  int i, j;
+  RTX_CODE code;
+  const char *format_ptr;
 
   /* No need to copy a permanent object.  */
   if (RTX_INTEGRATED_P (orig))
@@ -927,7 +912,7 @@ attr_copy_rtx (orig)
    in the attribute (or `alternative_name') to speed up subsequent
    `find_attr' calls and eliminate most `strcmp' calls.
 
-   Return the new expression, if any.   */
+   Return the new expression, if any.  */
 
 static rtx
 check_attr_test (exp, is_const, lineno)
@@ -963,11 +948,11 @@ check_attr_test (exp, is_const, lineno)
                  return exp;
                }
              else
-               fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
+               fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
            }
 
          if (is_const && ! attr->is_const)
-           fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
+           fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
                   XSTR (exp, 0));
 
          /* Copy this just to make it permanent,
@@ -983,8 +968,8 @@ check_attr_test (exp, is_const, lineno)
          if (attr->is_numeric)
            {
              for (p = XSTR (exp, 1); *p; p++)
-               if (*p < '0' || *p > '9')
-                 fatal ("Attribute `%s' takes only numeric values",
+               if (! ISDIGIT (*p))
+                 fatal ("attribute `%s' takes only numeric values",
                         XSTR (exp, 0));
            }
          else
@@ -995,7 +980,7 @@ check_attr_test (exp, is_const, lineno)
                  break;
 
              if (av == NULL)
-               fatal ("Unknown value `%s' for `%s' attribute",
+               fatal ("unknown value `%s' for `%s' attribute",
                       XSTR (exp, 1), XSTR (exp, 0));
            }
        }
@@ -1119,7 +1104,7 @@ check_attr_value (exp, attr)
          if (attr && attr->negative_ok && *p == '-')
            p++;
          for (; *p; p++)
-           if (*p > '9' || *p < '0')
+           if (! ISDIGIT (*p))
              {
                message_with_line (attr ? attr->lineno : 0,
                                   "non-numeric value for numeric attribute %s",
@@ -1453,7 +1438,7 @@ make_canonical (attr, exp)
       if (! strcmp (XSTR (exp, 0), "*"))
        {
          if (attr == 0 || attr->default_val == 0)
-           fatal ("(attr_value \"*\") used in invalid context.");
+           fatal ("(attr_value \"*\") used in invalid context");
          exp = attr->default_val->value;
        }
 
@@ -1644,9 +1629,8 @@ expand_delays ()
          newexp = attr_rtx (IF_THEN_ELSE, condexp,
                             make_numeric_value (1), make_numeric_value (0));
 
-         p = attr_printf (sizeof ("*delay__") + MAX_DIGITS * 2,
-                          "*delay_%d_%d",
-                          delay->num, i / 3);
+         p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
+                          "*delay_%d_%d", delay->num, i / 3);
          make_internal_attr (p, newexp, 1);
 
          if (have_annul_true)
@@ -1656,7 +1640,7 @@ expand_delays ()
              newexp = attr_rtx (IF_THEN_ELSE, condexp,
                                 make_numeric_value (1),
                                 make_numeric_value (0));
-             p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS * 2,
+             p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
                               "*annul_true_%d_%d", delay->num, i / 3);
              make_internal_attr (p, newexp, 1);
            }
@@ -1668,7 +1652,7 @@ expand_delays ()
              newexp = attr_rtx (IF_THEN_ELSE, condexp,
                                 make_numeric_value (1),
                                 make_numeric_value (0));
-             p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS * 2,
+             p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
                               "*annul_false_%d_%d", delay->num, i / 3);
              make_internal_attr (p, newexp, 1);
            }
@@ -1791,7 +1775,7 @@ operate_exp (op, left, right)
          return newexp;
        }
       else
-       fatal ("Badly formed attribute value");
+       fatal ("badly formed attribute value");
     }
 
   /* A hack to prevent expand_units from completely blowing up: ORX_OP does
@@ -1843,7 +1827,7 @@ operate_exp (op, left, right)
     }
 
   else
-    fatal ("Badly formed attribute value.");
+    fatal ("badly formed attribute value");
   /* NOTREACHED */
   return NULL;
 }
@@ -1921,7 +1905,8 @@ expand_units ()
                                           != unit->issue_delay.max);
          if (unit->needs_conflict_function)
            {
-             str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
+             str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
+                                 + MAX_DIGITS),
                                 "*%s_cost_%d", unit->name, op->num);
              make_internal_attr (str, issue_exp, 1);
            }
@@ -2150,7 +2135,8 @@ expand_units ()
                }
 
              /* Make an attribute for use in the blockage function.  */
-             str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
+             str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
+                                 + MAX_DIGITS),
                                 "*%s_block_%d", unit->name, op->num);
              make_internal_attr (str, blockage, 1);
            }
@@ -2183,12 +2169,13 @@ expand_units ()
              newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
              newexp = simplify_knowing (newexp, unit->condexp);
 
-             str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
+             str = attr_printf ((strlen (unit->name)
+                                 + sizeof "*_unit_blockage_range"),
                                 "*%s_unit_blockage_range", unit->name);
              make_internal_attr (str, newexp, 20);
            }
 
-         str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
+         str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
                             "*%s_unit_ready_cost", unit->name);
        }
       else
@@ -2230,7 +2217,7 @@ expand_units ()
        }
 
       /* Simplifying caseexp with simplify_by_exploding doesn't win.  */
-      str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
+      str = attr_printf (strlen (unit->name) + sizeof "*_cases",
                         "*%s_cases", unit->name);
       make_internal_attr (str, caseexp, 1);
     }
@@ -2265,10 +2252,10 @@ static rtx
 encode_units_mask (x)
      rtx x;
 {
-  register int i;
-  register int j;
-  register enum rtx_code code;
-  register const char *fmt;
+  int i;
+  int j;
+  enum rtx_code code;
+  const char *fmt;
 
   code = GET_CODE (x);
 
@@ -2450,11 +2437,11 @@ substitute_address (exp, no_address_fn, address_fn)
 static void
 make_length_attrs ()
 {
-  static const char *new_names[] = {"*insn_default_length",
+  static const char *const new_names[] = {"*insn_default_length",
                                      "*insn_variable_length_p",
                                      "*insn_current_length"};
-  static rtx (*no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
-  static rtx (*address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
+  static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
+  static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
   size_t i;
   struct attr_desc *length_attr, *new_attr;
   struct attr_value *av, *new_av;
@@ -2467,7 +2454,7 @@ make_length_attrs ()
     return;
 
   if (! length_attr->is_numeric)
-    fatal ("length attribute must be numeric.");
+    fatal ("length attribute must be numeric");
 
   length_attr->is_const = 0;
   length_attr->is_special = 1;
@@ -2593,7 +2580,7 @@ simplify_cond (exp, insn_code, insn_index)
       rtx newtest, newval;
 
       /* Simplify this test.  */
-      newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
+      newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
       tests[i] = newtest;
 
       newval = tests[i + 1];
@@ -2782,7 +2769,7 @@ insert_right_side (code, exp, term, insn_code, insn_index)
       newexp = attr_rtx (code, exp, term);
     }
 
-  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
+  return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
 }
 \f
 /* If we have an expression which AND's a bunch of
@@ -2910,8 +2897,8 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
 
       for (i = 0; i < XVECLEN (value, 0); i += 2)
        {
-         rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
-                                       insn_code, insn_index);
+         rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
+                                               insn_code, insn_index);
 
          SIMPLIFY_ALTERNATIVE (this);
 
@@ -2992,7 +2979,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
        {
          newexp = attr_rtx (GET_CODE (exp), left, right);
 
-         exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
+         exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
        }
     }
 
@@ -3015,7 +3002,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
        {
          newexp = attr_rtx (GET_CODE (exp), left, right);
 
-         exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
+         exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
        }
     }
 
@@ -3111,7 +3098,7 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
        {
          newexp = attr_rtx (GET_CODE (exp), left, right);
 
-         exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
+         exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
        }
     }
 
@@ -3134,7 +3121,7 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
        {
          newexp = attr_rtx (GET_CODE (exp), left, right);
 
-         exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
+         exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
        }
     }
 
@@ -3160,7 +3147,7 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
   return exp;
 }
 /* Compute approximate cost of the expression.  Used to decide whether
-   expression is cheap enought for inline.  */
+   expression is cheap enough for inline.  */
 static int
 attr_rtx_cost (x)
      rtx x;
@@ -3207,6 +3194,29 @@ attr_rtx_cost (x)
   return cost;
 }
 \f
+
+/* Simplify test expression and use temporary obstack in order to avoid
+   memory bloat.  Use RTX_UNCHANGING_P to avoid unnecesary simplifications
+   and avoid unnecesary copying if possible.  */
+
+static rtx
+simplify_test_exp_in_temp (exp, insn_code, insn_index)
+  rtx exp;
+  int insn_code, insn_index;
+{
+  rtx x;
+  struct obstack *old;
+  if (RTX_UNCHANGING_P (exp))
+    return exp;
+  old = rtl_obstack;
+  rtl_obstack = temp_obstack;
+  x = simplify_test_exp (exp, insn_code, insn_index);
+  rtl_obstack = old;
+  if (x == exp || rtl_obstack == temp_obstack)
+    return x;
+  return attr_copy_rtx (x);
+}
+
 /* Given an expression, see if it can be simplified for a particular insn
    code based on the values of other attributes being tested.  This can
    eliminate nested get_attr_... calls.
@@ -3295,7 +3305,7 @@ simplify_test_exp (exp, insn_code, insn_index)
        {
          i = compute_alternative_mask (exp, AND);
          if (i & ~insn_alternatives[insn_code])
-           fatal ("Invalid alternative specified for pattern number %d",
+           fatal ("invalid alternative specified for pattern number %d",
                   insn_index);
 
          /* If all alternatives are excluded, this is false.  */
@@ -3379,7 +3389,7 @@ simplify_test_exp (exp, insn_code, insn_index)
        {
          i = compute_alternative_mask (exp, IOR);
          if (i & ~insn_alternatives[insn_code])
-           fatal ("Invalid alternative specified for pattern number %d",
+           fatal ("invalid alternative specified for pattern number %d",
                   insn_index);
 
          /* If all alternatives are included, this is true.  */
@@ -3456,7 +3466,7 @@ simplify_test_exp (exp, insn_code, insn_index)
 
       /* Look at the value for this insn code in the specified attribute.
         We normally can replace this comparison with the condition that
-        would give this insn the values being tested for.   */
+        would give this insn the values being tested for.  */
       if (XSTR (exp, 0) != alternative_name
          && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
        for (av = attr->first_value; av; av = av->next)
@@ -3464,13 +3474,10 @@ simplify_test_exp (exp, insn_code, insn_index)
            if (ie->insn_code == insn_code)
              {
                rtx x;
-               struct obstack *old = rtl_obstack;
-               rtl_obstack = temp_obstack;
                x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
                x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
-               rtl_obstack = old;
                if (attr_rtx_cost(x) < 20)
-                 return attr_copy_rtx (x);
+                 return x;
              }
       break;
 
@@ -3499,7 +3506,6 @@ optimize_attrs ()
   struct attr_value *av;
   struct insn_ent *ie;
   rtx newexp;
-  int something_changed = 1;
   int i;
   struct attr_value_list
   {
@@ -3556,42 +3562,42 @@ optimize_attrs ()
       for (iv = insn_code_values[i]; iv; iv = iv->next)
        clear_struct_flag (iv->av->value);
 
-      /* Loop until nothing changes for one iteration.  */
-      something_changed = 1;
-      while (something_changed)
+      for (iv = insn_code_values[i]; iv; iv = iv->next)
        {
-         something_changed = 0;
-         for (iv = insn_code_values[i]; iv; iv = iv->next)
-           {
-             struct obstack *old = rtl_obstack;
+         struct obstack *old = rtl_obstack;
 
-             attr = iv->attr;
-             av = iv->av;
-             ie = iv->ie;
-             if (GET_CODE (av->value) != COND)
-               continue;
+         attr = iv->attr;
+         av = iv->av;
+         ie = iv->ie;
+         if (GET_CODE (av->value) != COND)
+           continue;
 
-             rtl_obstack = temp_obstack;
+         rtl_obstack = temp_obstack;
 #if 0 /* This was intended as a speed up, but it was slower.  */
-             if (insn_n_alternatives[ie->insn_code] > 6
-                 && count_sub_rtxs (av->value, 200) >= 200)
-               newexp = simplify_by_alternatives (av->value, ie->insn_code,
-                                                  ie->insn_index);
-             else
+         if (insn_n_alternatives[ie->insn_code] > 6
+             && count_sub_rtxs (av->value, 200) >= 200)
+           newexp = simplify_by_alternatives (av->value, ie->insn_code,
+                                              ie->insn_index);
+         else
 #endif
-               newexp = simplify_cond (av->value, ie->insn_code,
-                                       ie->insn_index);
+         newexp = av->value;
+         while (GET_CODE (newexp) == COND)
+           {
+             rtx newexp2 = simplify_cond (newexp, ie->insn_code,
+                                          ie->insn_index);
+             if (newexp2 == newexp)
+               break;
+             newexp = newexp2;
+           }
 
-             rtl_obstack = old;
-             if (newexp != av->value)
-               {
-                 newexp = attr_copy_rtx (newexp);
-                 remove_insn_ent (av, ie);
-                 av = get_attr_value (newexp, attr, ie->insn_code);
-                 iv->av = av;
-                 insert_insn_ent (av, ie);
-                 something_changed = 1;
-               }
+         rtl_obstack = old;
+         if (newexp != av->value)
+           {
+             newexp = attr_copy_rtx (newexp);
+             remove_insn_ent (av, ie);
+             av = get_attr_value (newexp, attr, ie->insn_code);
+             iv->av = av;
+             insert_insn_ent (av, ie);
            }
        }
     }
@@ -4010,7 +4016,7 @@ static rtx
 simplify_with_current_value_aux (exp)
      rtx exp;
 {
-  register int i;
+  int i;
   rtx cond;
 
   switch (GET_CODE (exp))
@@ -4089,10 +4095,10 @@ static void
 clear_struct_flag (x)
      rtx x;
 {
-  register int i;
-  register int j;
-  register enum rtx_code code;
-  register const char *fmt;
+  int i;
+  int j;
+  enum rtx_code code;
+  const char *fmt;
 
   MEM_IN_STRUCT_P (x) = 0;
   if (RTX_UNCHANGING_P (x))
@@ -4147,10 +4153,10 @@ count_sub_rtxs (x, max)
      rtx x;
      int max;
 {
-  register int i;
-  register int j;
-  register enum rtx_code code;
-  register const char *fmt;
+  int i;
+  int j;
+  enum rtx_code code;
+  const char *fmt;
   int total = 0;
 
   code = GET_CODE (x);
@@ -4739,7 +4745,7 @@ write_test_expr (exp, flags)
       if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
        {
          if (GET_MODE (exp) == VOIDmode)
-           fatal ("Null MATCH_OPERAND specified as test");
+           fatal ("null MATCH_OPERAND specified as test");
          else
            printf ("GET_MODE (operands[%d]) == %smode",
                    XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
@@ -4893,8 +4899,8 @@ static void
 walk_attr_value (exp)
      rtx exp;
 {
-  register int i, j;
-  register const char *fmt;
+  int i, j;
+  const char *fmt;
   RTX_CODE code;
 
   if (exp == NULL)
@@ -5262,11 +5268,11 @@ write_expr_attr_cache (p, attr)
        return 0;
 
       if (!attr->is_numeric)
-       printf ("  register enum attr_%s ", attr->name);
+       printf ("  enum attr_%s ", attr->name);
       else if (attr->unsigned_p)
-       printf ("  register unsigned int ");
+       printf ("  unsigned int ");
       else
-       printf ("  register int ");
+       printf ("  int ");
 
       printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
       return 1;
@@ -5311,7 +5317,7 @@ write_toplevel_expr (p)
       if (!attr->is_const)
        write_expr_attr_cache (p, attr);
 
-  printf ("  register unsigned long accum = 0;\n\n");
+  printf ("  unsigned long accum = 0;\n\n");
 
   while (GET_CODE (p) == IOR)
     {
@@ -5514,7 +5520,7 @@ write_eligible_delay (kind)
   printf ("int\n");
   printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
          kind);
-  printf ("     rtx delay_insn;\n");
+  printf ("     rtx delay_insn ATTRIBUTE_UNUSED;\n");
   printf ("     int slot;\n");
   printf ("     rtx candidate_insn;\n");
   printf ("     int flags ATTRIBUTE_UNUSED;\n");
@@ -5643,7 +5649,7 @@ write_function_unit_info ()
      the function units.   The name is included for documentation purposes
      only.  */
 
-  printf ("struct function_unit_desc function_units[] = {\n");
+  printf ("const struct function_unit_desc function_units[] = {\n");
 
   /* Write out the descriptions in numeric order, but don't force that order
      on the list.  Doing so increases the runtime of genattrtab.c.  */
@@ -5969,11 +5975,11 @@ extend_range (range, min, max)
 
 static rtx
 copy_rtx_unchanging (orig)
-     register rtx orig;
+     rtx orig;
 {
 #if 0
-  register rtx copy;
-  register RTX_CODE code;
+  rtx copy;
+  RTX_CODE code;
 #endif
 
   if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
@@ -6059,9 +6065,9 @@ main (argc, argv)
   progname = "genattrtab";
 
   if (argc <= 1)
-    fatal ("No input file name.");
+    fatal ("no input file name");
 
-  if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
+  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
     return (FATAL_EXIT_CODE);
 
   obstack_init (hash_obstack);