OSDN Git Service

* Makefile.in (timevar.o): Depend on flags.h.
[pf3gnuchains/gcc-fork.git] / gcc / genattrtab.c
index f6008df..2dab1b6 100644 (file)
@@ -1,5 +1,6 @@
 /* Generate code from machine description to compute values of attributes.
-   Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -98,7 +99,7 @@ Boston, MA 02111-1307, USA.  */
 #include "hconfig.h"
 #include "system.h"
 #include "rtl.h"
-#include "insn-config.h"       /* For REGISTER_CONSTRAINTS */
+#include "ggc.h"
 
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
@@ -107,6 +108,7 @@ Boston, MA 02111-1307, USA.  */
 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
    /usr/include/sys/stdtypes.h on Sun OS 4.x.  */
 #include "obstack.h"
+#include "errors.h"
 
 static struct obstack obstack, obstack1, obstack2;
 struct obstack *rtl_obstack = &obstack;
@@ -116,13 +118,6 @@ struct obstack *temp_obstack = &obstack2;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
-static void fatal PVPROTO ((const char *, ...))
-  ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
-
 /* enough space to reserve for printing out ints */
 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
 
@@ -221,7 +216,7 @@ struct function_unit_op
 
 struct function_unit
 {
-  char *name;                  /* Function unit name.  */
+  const char *name;            /* Function unit name.  */
   struct function_unit *next;  /* Next function unit.  */
   int num;                     /* Ordinal of this unit type.  */
   int multiplicity;            /* Number of units of this type.  */
@@ -321,7 +316,7 @@ static int *insn_alternatives;
    This is the hashed, unique string for the numeral
    whose value is chosen alternative.  */
 
-static char *current_alternative_string;
+static const char *current_alternative_string;
 
 /* Used to simplify expressions.  */
 
@@ -359,102 +354,107 @@ int optimize = 0;
 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
    They won't actually be used.  */
 
-struct _global_rtl global_rtl;
+rtx global_rtl[GR_MAX];
 rtx pic_offset_table_rtx;
 
-static void attr_hash_add_rtx  PROTO((int, rtx));
-static void attr_hash_add_string PROTO((int, char *));
-static rtx attr_rtx            PVPROTO((enum rtx_code, ...));
-static char *attr_printf       PVPROTO((int, const char *, ...))
+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 *, ...))
   ATTRIBUTE_PRINTF_2;
-static char *attr_string        PROTO((const char *, int));
-static rtx check_attr_test     PROTO((rtx, int));
-static rtx check_attr_value    PROTO((rtx, struct attr_desc *));
-static rtx convert_set_attr_alternative PROTO((rtx, int, int));
-static rtx convert_set_attr    PROTO((rtx, int, int));
-static void check_defs         PROTO((void));
+static char *attr_string        PARAMS ((const char *, int));
+static rtx check_attr_test     PARAMS ((rtx, int));
+static rtx check_attr_value    PARAMS ((rtx, struct attr_desc *));
+static rtx convert_set_attr_alternative PARAMS ((rtx, int, int));
+static rtx convert_set_attr    PARAMS ((rtx, int, int));
+static void check_defs         PARAMS ((void));
 #if 0
-static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
+static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
 #endif
-static rtx make_canonical      PROTO((struct attr_desc *, rtx));
-static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
-static rtx copy_rtx_unchanging PROTO((rtx));
-static rtx copy_boolean                PROTO((rtx));
-static void expand_delays      PROTO((void));
-static rtx operate_exp         PROTO((enum operator, rtx, rtx));
-static void expand_units       PROTO((void));
-static rtx simplify_knowing    PROTO((rtx, rtx));
-static rtx encode_units_mask   PROTO((rtx));
-static void fill_attr          PROTO((struct attr_desc *));
+static rtx make_canonical      PARAMS ((struct attr_desc *, rtx));
+static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
+static rtx copy_rtx_unchanging PARAMS ((rtx));
+static rtx copy_boolean                PARAMS ((rtx));
+static void expand_delays      PARAMS ((void));
+static rtx operate_exp         PARAMS ((enum operator, rtx, rtx));
+static void expand_units       PARAMS ((void));
+static rtx simplify_knowing    PARAMS ((rtx, rtx));
+static rtx encode_units_mask   PARAMS ((rtx));
+static void fill_attr          PARAMS ((struct attr_desc *));
 /* dpx2 compiler chokes if we specify the arg types of the args.  */
-static rtx substitute_address  PROTO((rtx, rtx (*) (), rtx (*) ()));
-static void make_length_attrs  PROTO((void));
-static rtx identity_fn         PROTO((rtx));
-static rtx zero_fn             PROTO((rtx));
-static rtx one_fn              PROTO((rtx));
-static rtx max_fn              PROTO((rtx));
-static void write_length_unit_log PROTO ((void));
-static rtx simplify_cond       PROTO((rtx, int, int));
+static rtx substitute_address  PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
+static void make_length_attrs  PARAMS ((void));
+static rtx identity_fn         PARAMS ((rtx));
+static rtx zero_fn             PARAMS ((rtx));
+static rtx one_fn              PARAMS ((rtx));
+static rtx max_fn              PARAMS ((rtx));
+static void write_length_unit_log PARAMS ((void));
+static rtx simplify_cond       PARAMS ((rtx, int, int));
 #if 0
-static rtx simplify_by_alternatives PROTO((rtx, int, int));
+static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
 #endif
-static rtx simplify_by_exploding PROTO((rtx));
-static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
-static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
-static int add_values_to_cover PROTO((struct dimension *));
-static int increment_current_value PROTO((struct dimension *, int));
-static rtx test_for_current_value PROTO((struct dimension *, int));
-static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
-static rtx simplify_with_current_value_aux PROTO((rtx));
-static void clear_struct_flag PROTO((rtx));
-static int count_sub_rtxs    PROTO((rtx, int));
-static void remove_insn_ent  PROTO((struct attr_value *, struct insn_ent *));
-static void insert_insn_ent  PROTO((struct attr_value *, struct insn_ent *));
-static rtx insert_right_side   PROTO((enum rtx_code, rtx, rtx, int, int));
-static rtx make_alternative_compare PROTO((int));
-static int compute_alternative_mask PROTO((rtx, enum rtx_code));
-static rtx evaluate_eq_attr    PROTO((rtx, rtx, int, int));
-static rtx simplify_and_tree   PROTO((rtx, rtx *, int, int));
-static rtx simplify_or_tree    PROTO((rtx, rtx *, int, int));
-static rtx simplify_test_exp   PROTO((rtx, int, int));
-static void optimize_attrs     PROTO((void));
-static void gen_attr           PROTO((rtx));
-static int count_alternatives  PROTO((rtx));
-static int compares_alternatives_p PROTO((rtx));
-static int contained_in_p      PROTO((rtx, rtx));
-static void gen_insn           PROTO((rtx));
-static void gen_delay          PROTO((rtx));
-static void gen_unit           PROTO((rtx));
-static void write_test_expr    PROTO((rtx, int));
-static int max_attr_value      PROTO((rtx, int*));
-static int or_attr_value       PROTO((rtx, int*));
-static void walk_attr_value    PROTO((rtx));
-static void write_attr_get     PROTO((struct attr_desc *));
-static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
-static void write_attr_set     PROTO((struct attr_desc *, int, rtx,
+static rtx simplify_by_exploding PARAMS ((rtx));
+static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
+static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
+static int add_values_to_cover PARAMS ((struct dimension *));
+static int increment_current_value PARAMS ((struct dimension *, int));
+static rtx test_for_current_value PARAMS ((struct dimension *, int));
+static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
+static rtx simplify_with_current_value_aux PARAMS ((rtx));
+static void clear_struct_flag PARAMS ((rtx));
+static int count_sub_rtxs    PARAMS ((rtx, int));
+static void remove_insn_ent  PARAMS ((struct attr_value *, struct insn_ent *));
+static void insert_insn_ent  PARAMS ((struct attr_value *, struct insn_ent *));
+static rtx insert_right_side   PARAMS ((enum rtx_code, rtx, rtx, int, int));
+static rtx make_alternative_compare PARAMS ((int));
+static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
+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 void optimize_attrs     PARAMS ((void));
+static void gen_attr           PARAMS ((rtx));
+static int count_alternatives  PARAMS ((rtx));
+static int compares_alternatives_p PARAMS ((rtx));
+static int contained_in_p      PARAMS ((rtx, rtx));
+static void gen_insn           PARAMS ((rtx));
+static void gen_delay          PARAMS ((rtx));
+static void gen_unit           PARAMS ((rtx));
+static void write_test_expr    PARAMS ((rtx, int));
+static int max_attr_value      PARAMS ((rtx, int*));
+static int or_attr_value       PARAMS ((rtx, int*));
+static void walk_attr_value    PARAMS ((rtx));
+static void write_attr_get     PARAMS ((struct attr_desc *));
+static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
+static void write_attr_set     PARAMS ((struct attr_desc *, int, rtx,
                                       const char *, const char *, rtx,
                                       int, int));
-static void write_attr_case    PROTO((struct attr_desc *, struct attr_value *,
+static void write_attr_case    PARAMS ((struct attr_desc *, struct attr_value *,
                                       int, const char *, const char *, int, rtx));
-static void write_unit_name    PROTO((const char *, int, const char *));
-static void write_attr_valueq  PROTO((struct attr_desc *, char *));
-static void write_attr_value   PROTO((struct attr_desc *, rtx));
-static void write_upcase       PROTO((char *));
-static void write_indent       PROTO((int));
-static void write_eligible_delay PROTO((const char *));
-static void write_function_unit_info PROTO((void));
-static void write_complex_function PROTO((struct function_unit *, const char *,
+static void write_unit_name    PARAMS ((const char *, int, const char *));
+static void write_attr_valueq  PARAMS ((struct attr_desc *, const char *));
+static void write_attr_value   PARAMS ((struct attr_desc *, rtx));
+static void write_upcase       PARAMS ((const char *));
+static void write_indent       PARAMS ((int));
+static void write_eligible_delay PARAMS ((const char *));
+static void write_function_unit_info PARAMS ((void));
+static void write_complex_function PARAMS ((struct function_unit *, const char *,
                                          const char *));
-static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
-static void write_toplevel_expr        PROTO((rtx));
-static int n_comma_elts                PROTO((char *));
-static char *next_comma_elt    PROTO((char **));
-static struct attr_desc *find_attr PROTO((const char *, int));
-static void make_internal_attr PROTO((const char *, rtx, int));
-static struct attr_value *find_most_used  PROTO((struct attr_desc *));
-static rtx find_single_value   PROTO((struct attr_desc *));
-static rtx make_numeric_value  PROTO((int));
-static void extend_range       PROTO((struct range *, int, int));
+static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
+static void write_toplevel_expr        PARAMS ((rtx));
+static void write_const_num_delay_slots PARAMS ((void));
+static int n_comma_elts                PARAMS ((const char *));
+static char *next_comma_elt    PARAMS ((const char **));
+static struct attr_desc *find_attr PARAMS ((const char *, int));
+static void make_internal_attr PARAMS ((const char *, rtx, int));
+static struct attr_value *find_most_used  PARAMS ((struct attr_desc *));
+static rtx find_single_value   PARAMS ((struct attr_desc *));
+static rtx make_numeric_value  PARAMS ((int));
+static void extend_range       PARAMS ((struct range *, int, int));
+static rtx attr_eq             PARAMS ((const char *, const char *));
+static const char *attr_numeral        PARAMS ((int));
+static int attr_equal_p                PARAMS ((rtx, rtx));
+static rtx attr_copy_rtx       PARAMS ((rtx));
 
 #define oballoc(size) obstack_alloc (hash_obstack, size)
 
@@ -536,15 +536,15 @@ attr_hash_add_string (hashcode, str)
 
 /*VARARGS1*/
 static rtx
-attr_rtx VPROTO((enum rtx_code code, ...))
+attr_rtx VPARAMS ((enum rtx_code code, ...))
 {
 #ifndef ANSI_PROTOTYPES
   enum rtx_code code;
 #endif
   va_list p;
   register int i;              /* Array indices...                     */
-  register char *fmt;          /* Current rtx's format...              */
-  register rtx rt_val;         /* RTX to return to caller...           */
+  register const char *fmt;    /* Current rtx's format...              */
+  register rtx rt_val = NULL_RTX;/* RTX to return to caller...         */
   int hashcode;
   register struct attr_hash *h;
   struct obstack *old_obstack = rtl_obstack;
@@ -622,7 +622,7 @@ attr_rtx VPROTO((enum rtx_code code, ...))
   else if (GET_RTX_LENGTH (code) == 1
           && GET_RTX_FORMAT (code)[0] == 's')
     {
-      char * arg0 = va_arg (p, char *);
+      char *arg0 = va_arg (p, char *);
 
       if (code == SYMBOL_REF)
        arg0 = attr_string (arg0, strlen (arg0));
@@ -668,9 +668,15 @@ attr_rtx VPROTO((enum rtx_code code, ...))
     {
       HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
       if (arg0 == 0)
-       return false_rtx;
+       {
+         va_end (p);
+         return false_rtx;
+       }
       if (arg0 == 1)
-       return true_rtx;
+       {
+         va_end (p);
+         return true_rtx;
+       }
       goto nohash;
     }
   else
@@ -733,7 +739,7 @@ attr_rtx VPROTO((enum rtx_code code, ...))
 
 /*VARARGS2*/
 static char *
-attr_printf VPROTO((register int len, const char *fmt, ...))
+attr_printf VPARAMS ((register int len, const char *fmt, ...))
 {
 #ifndef ANSI_PROTOTYPES
   register int len;
@@ -757,15 +763,15 @@ attr_printf VPROTO((register int len, const char *fmt, ...))
   return attr_string (str, strlen (str));
 }
 
-rtx
+static rtx
 attr_eq (name, value)
-     char *name, *value;
+     const char *name, *value;
 {
   return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
                   attr_string (value, strlen (value)));
 }
 
-char *
+static const char *
 attr_numeral (n)
      int n;
 {
@@ -811,7 +817,7 @@ attr_string (str, len)
    taking advantage of the fact that if both are hashed
    then they can't be equal unless they are the same object.  */
 
-int
+static int
 attr_equal_p (x, y)
      rtx x, y;
 {
@@ -823,14 +829,14 @@ attr_equal_p (x, y)
    descending to all depths, but not copying any
    permanent hashed subexpressions.  */
 
-rtx
+static rtx
 attr_copy_rtx (orig)
      register rtx orig;
 {
   register rtx copy;
   register int i, j;
   register RTX_CODE code;
-  register char *format_ptr;
+  register const char *format_ptr;
 
   /* No need to copy a permanent object.  */
   if (RTX_INTEGRATED_P (orig))
@@ -926,7 +932,7 @@ check_attr_test (exp, is_const)
 {
   struct attr_desc *attr;
   struct attr_value *av;
-  char *name_ptr, *p;
+  const char *name_ptr, *p;
   rtx orexp, newexp;
 
   switch (GET_CODE (exp))
@@ -1073,7 +1079,7 @@ check_attr_value (exp, attr)
      struct attr_desc *attr;
 {
   struct attr_value *av;
-  char *p;
+  const char *p;
   int i;
 
   switch (GET_CODE (exp))
@@ -1211,7 +1217,7 @@ convert_set_attr_alternative (exp, num_alt, insn_index)
 
   for (i = 0; i < num_alt - 1; i++)
     {
-      char *p;
+      const char *p;
       p = attr_numeral (i);
 
       XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
@@ -1239,7 +1245,7 @@ convert_set_attr (exp, num_alt, insn_index)
      int insn_index;
 {
   rtx newexp;
-  char *name_ptr;
+  const char *name_ptr;
   char *p;
   int n;
 
@@ -1354,8 +1360,7 @@ convert_const_symbol_ref (exp, attr)
       strcat (p, "_");
       strcat (p, XSTR (av->value, 0));
       for (; *p != '\0'; p++)
-       if (*p >= 'a' && *p <= 'z')
-         *p -= 'a' - 'A';
+       *p = TOUPPER (*p);
 
       value = attr_rtx (SYMBOL_REF, string);
       RTX_UNCHANGING_P (value) = 1;
@@ -1724,7 +1729,8 @@ operate_exp (op, left, right)
             give the same value), optimize it away.  */
          if (allsame)
            {
-             obstack_free (rtl_obstack, newexp);
+             if (!ggc_p)
+               obstack_free (rtl_obstack, newexp);
              return operate_exp (op, left, XEXP (right, 1));
            }
 
@@ -1732,7 +1738,8 @@ operate_exp (op, left, right)
             just use that.  */
          if (rtx_equal_p (newexp, right))
            {
-             obstack_free (rtl_obstack, newexp);
+             if (!ggc_p)
+               obstack_free (rtl_obstack, newexp);
              return right;
            }
 
@@ -1781,7 +1788,8 @@ operate_exp (op, left, right)
         optimize it away.  */
       if (allsame)
        {
-         obstack_free (rtl_obstack, newexp);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, newexp);
          return operate_exp (op, XEXP (left, 1), right);
        }
 
@@ -1789,7 +1797,8 @@ operate_exp (op, left, right)
         just use that.  */
       if (rtx_equal_p (newexp, left))
        {
-         obstack_free (rtl_obstack, newexp);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, newexp);
          return left;
        }
 
@@ -2082,25 +2091,7 @@ expand_units ()
 
          for (op = unit->ops; op; op = op->next)
            {
-#ifdef HAIFA
              rtx blockage = op->issue_exp;
-#else
-             rtx blockage = operate_exp (POS_MINUS_OP, readycost,
-                                         make_numeric_value (1));
-
-             if (unit->simultaneity != 0)
-               {
-                 rtx filltime = make_numeric_value ((unit->simultaneity - 1)
-                                                    * unit->issue_delay.min);
-                 blockage = operate_exp (MIN_OP, blockage, filltime);
-               }
-
-             blockage = operate_exp (POS_MINUS_OP,
-                                     make_numeric_value (op->ready),
-                                     blockage);
-
-             blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
-#endif
              blockage = simplify_knowing (blockage, unit->condexp);
 
              /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
@@ -2214,7 +2205,7 @@ simplify_knowing (exp, known_true)
 {
   if (GET_CODE (exp) != CONST_STRING)
     {
-      int unknown, max;
+      int unknown = 0, max;
       max = max_attr_value (exp, &unknown);
       if (! unknown)
        {
@@ -2238,7 +2229,7 @@ encode_units_mask (x)
   register int i;
   register int j;
   register enum rtx_code code;
-  register char *fmt;
+  register const char *fmt;
 
   code = GET_CODE (x);
 
@@ -2345,8 +2336,8 @@ fill_attr (attr)
 static rtx
 substitute_address (exp, no_address_fn, address_fn)
      rtx exp;
-     rtx (*no_address_fn) ();
-     rtx (*address_fn) ();
+     rtx (*no_address_fn) PARAMS ((rtx));
+     rtx (*address_fn) PARAMS ((rtx));
 {
   int i;
   rtx newexp;
@@ -2422,8 +2413,8 @@ make_length_attrs ()
   static const char *new_names[] = {"*insn_default_length",
                                      "*insn_variable_length_p",
                                      "*insn_current_length"};
-  static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
-  static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
+  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};
   size_t i;
   struct attr_desc *length_attr, *new_attr;
   struct attr_value *av, *new_av;
@@ -2541,14 +2532,14 @@ simplify_cond (exp, insn_code, insn_index)
   rtx defval = XEXP (exp, 1);
   rtx new_defval = XEXP (exp, 1);
   int len = XVECLEN (exp, 0);
-  rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
+  rtx *tests = (rtx *) alloca (len * sizeof (rtx));
   int allsame = 1;
   char *first_spacer;
 
   /* This lets us free all storage allocated below, if appropriate.  */
   first_spacer = (char *) obstack_finish (rtl_obstack);
 
-  bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
+  bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtx));
 
   /* See if default value needs simplification.  */
   if (GET_CODE (defval) == COND)
@@ -2561,10 +2552,10 @@ simplify_cond (exp, insn_code, insn_index)
       rtx newtest, newval;
 
       /* Simplify this test.  */
-      newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
-      tests[i].rtx = newtest;
+      newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
+      tests[i] = newtest;
 
-      newval = tests[i + 1].rtx;
+      newval = tests[i + 1];
       /* See if this value may need simplification.  */
       if (GET_CODE (newval) == COND)
        newval = simplify_cond (newval, insn_code, insn_index);
@@ -2575,7 +2566,7 @@ simplify_cond (exp, insn_code, insn_index)
          /* If test is true, make this value the default
             and discard this + any following tests.  */
          len = i;
-         defval = tests[i + 1].rtx;
+         defval = tests[i + 1];
          new_defval = newval;
        }
 
@@ -2583,33 +2574,33 @@ simplify_cond (exp, insn_code, insn_index)
        {
          /* If test is false, discard it and its value.  */
          for (j = i; j < len - 2; j++)
-           tests[j].rtx = tests[j + 2].rtx;
+           tests[j] = tests[j + 2];
          len -= 2;
        }
 
-      else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
+      else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
        {
          /* If this value and the value for the prev test are the same,
             merge the tests.  */
 
-         tests[i - 2].rtx
-           = insert_right_side (IOR, tests[i - 2].rtx, newtest,
+         tests[i - 2]
+           = insert_right_side (IOR, tests[i - 2], newtest,
                                 insn_code, insn_index);
 
          /* Delete this test/value.  */
          for (j = i; j < len - 2; j++)
-           tests[j].rtx = tests[j + 2].rtx;
+           tests[j] = tests[j + 2];
          len -= 2;
        }
 
       else
-       tests[i + 1].rtx = newval;
+       tests[i + 1] = newval;
     }
 
   /* If the last test in a COND has the same value
      as the default value, that test isn't needed.  */
 
-  while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
+  while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
     len -= 2;
 
   /* See if we changed anything.  */
@@ -2617,7 +2608,7 @@ simplify_cond (exp, insn_code, insn_index)
     allsame = 0;
   else
     for (i = 0; i < len; i++)
-      if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
+      if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
        {
          allsame = 0;
          break;
@@ -2625,14 +2616,16 @@ simplify_cond (exp, insn_code, insn_index)
 
   if (len == 0)
     {
-      obstack_free (rtl_obstack, first_spacer);
+      if (!ggc_p)
+       obstack_free (rtl_obstack, first_spacer);
       if (GET_CODE (defval) == COND)
        return simplify_cond (defval, insn_code, insn_index);
       return defval;
     }
   else if (allsame)
     {
-      obstack_free (rtl_obstack, first_spacer);
+      if (!ggc_p)
+       obstack_free (rtl_obstack, first_spacer);
       return exp;
     }
   else
@@ -2641,7 +2634,7 @@ simplify_cond (exp, insn_code, insn_index)
 
       XVEC (newexp, 0) = rtvec_alloc (len);
       bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
-            len * sizeof (rtunion));
+            len * sizeof (rtx));
       XEXP (newexp, 1) = new_defval;
       return newexp;
     }
@@ -2768,7 +2761,7 @@ compute_alternative_mask (exp, code)
      rtx exp;
      enum rtx_code code;
 {
-  char *string;
+  const char *string;
   if (GET_CODE (exp) == code)
     return compute_alternative_mask (XEXP (exp, 0), code)
           | compute_alternative_mask (XEXP (exp, 1), code);
@@ -2850,8 +2843,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
       strcat (string, "_");
       strcat (string, XSTR (exp, 1));
       for (p = string; *p ; p++)
-       if (*p >= 'a' && *p <= 'z')
-         *p -= 'a' - 'A';
+       *p = TOUPPER (*p);
       
       newexp = attr_rtx (EQ, value,
                         attr_rtx (SYMBOL_REF,
@@ -3162,14 +3154,16 @@ simplify_test_exp (exp, insn_code, insn_index)
       SIMPLIFY_ALTERNATIVE (left);
       if (left == false_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return false_rtx;
        }
       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
       SIMPLIFY_ALTERNATIVE (right);
       if (left == false_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return false_rtx;
        }
 
@@ -3201,7 +3195,8 @@ simplify_test_exp (exp, insn_code, insn_index)
 
       if (left == false_rtx || right == false_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return false_rtx;
        }
       else if (left == true_rtx)
@@ -3260,14 +3255,16 @@ simplify_test_exp (exp, insn_code, insn_index)
       SIMPLIFY_ALTERNATIVE (left);
       if (left == true_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return true_rtx;
        }
       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
       SIMPLIFY_ALTERNATIVE (right);
       if (right == true_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return true_rtx;
        }
 
@@ -3277,7 +3274,8 @@ simplify_test_exp (exp, insn_code, insn_index)
 
       if (right == true_rtx || left == true_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return true_rtx;
        }
       else if (left == false_rtx)
@@ -3364,12 +3362,14 @@ simplify_test_exp (exp, insn_code, insn_index)
 
       if (left == false_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return true_rtx;
        }
       else if (left == true_rtx)
        {
-         obstack_free (rtl_obstack, spacer);
+         if (!ggc_p)
+           obstack_free (rtl_obstack, spacer);
          return false_rtx;
        }
 
@@ -3531,7 +3531,8 @@ optimize_attrs ()
                  insert_insn_ent (av, ie);
                  something_changed = 1;
                }
-             obstack_free (temp_obstack, spacer);
+             if (!ggc_p)
+               obstack_free (temp_obstack, spacer);
            }
        }
     }
@@ -3607,7 +3608,7 @@ simplify_by_exploding (exp)
     {
       /* Pull the first attribute value from the list and record that
         attribute as another dimension in the attribute space.  */
-      char *name = XSTR (XEXP (list, 0), 0);
+      const char *name = XSTR (XEXP (list, 0), 0);
       rtx *prev;
 
       if ((space[ndim].attr = find_attr (name, 0)) == 0
@@ -4024,7 +4025,7 @@ clear_struct_flag (x)
   register int i;
   register int j;
   register enum rtx_code code;
-  register char *fmt;
+  register const char *fmt;
 
   MEM_IN_STRUCT_P (x) = 0;
   if (RTX_UNCHANGING_P (x))
@@ -4082,7 +4083,7 @@ count_sub_rtxs (x, max)
   register int i;
   register int j;
   register enum rtx_code code;
-  register char *fmt;
+  register const char *fmt;
   int total = 0;
 
   code = GET_CODE (x);
@@ -4139,7 +4140,7 @@ gen_attr (exp)
 {
   struct attr_desc *attr;
   struct attr_value *av;
-  char *name_ptr;
+  const char *name_ptr;
   char *p;
 
   /* Make a new attribute structure.  Check for duplicate by looking at
@@ -4191,7 +4192,7 @@ count_alternatives (exp)
      rtx exp;
 {
   int i, j, n;
-  char *fmt;
+  const char *fmt;
   
   if (GET_CODE (exp) == MATCH_OPERAND)
     return n_comma_elts (XSTR (exp, 2));
@@ -4229,7 +4230,7 @@ compares_alternatives_p (exp)
      rtx exp;
 {
   int i, j;
-  char *fmt;
+  const char *fmt;
 
   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
     return 1;
@@ -4262,7 +4263,7 @@ contained_in_p (inner, exp)
      rtx exp;
 {
   int i, j;
-  char *fmt;
+  const char *fmt;
 
   if (rtx_equal_p (inner, exp))
     return 1;
@@ -4373,7 +4374,7 @@ gen_unit (def)
 {
   struct function_unit *unit;
   struct function_unit_op *op;
-  char *name = XSTR (def, 0);
+  const char *name = XSTR (def, 0);
   int multiplicity = XINT (def, 1);
   int simultaneity = XINT (def, 2);
   rtx condexp = XEXP (def, 3);
@@ -4790,7 +4791,7 @@ walk_attr_value (exp)
      rtx exp;
 {
   register int i, j;
-  register char *fmt;
+  register const char *fmt;
   RTX_CODE code;
 
   if (exp == NULL)
@@ -4862,6 +4863,21 @@ write_attr_get (attr)
      switch we will generate.  */
   common_av = find_most_used (attr);
 
+  /* Write out prototype of function. */
+  if (!attr->is_numeric)
+    printf ("extern enum attr_%s ", attr->name);
+  else if (attr->unsigned_p)
+    printf ("extern unsigned int ");
+  else
+    printf ("extern int ");
+  /* If the attribute name starts with a star, the remainder is the name of
+     the subroutine to use, instead of `get_attr_...'.  */
+  if (attr->name[0] == '*')
+    printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
+  else
+    printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
+           (attr->is_const ? "void" : "rtx"));
+
   /* Write out start of function, then all values with explicit `case' lines,
      then a `default', then the value with the most uses.  */
   if (!attr->is_numeric)
@@ -5112,12 +5128,10 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
 
   if (must_constrain)
     {
-#ifdef REGISTER_CONSTRAINTS
       write_indent (indent + 2);
       printf ("if (! constrain_operands (reload_completed))\n");
       write_indent (indent + 2);
       printf ("  fatal_insn_not_found (insn);\n");
-#endif
     }
 
   write_attr_set (attr, indent + 2, av->value, prefix, suffix,
@@ -5139,7 +5153,7 @@ write_expr_attr_cache (p, attr)
      rtx p;
      struct attr_desc *attr;
 {
-  char *fmt;
+  const char *fmt;
   int i, ie, j, je;
 
   if (GET_CODE (p) == EQ_ATTR)
@@ -5239,7 +5253,7 @@ write_unit_name (prefix, num, suffix)
 static void
 write_attr_valueq (attr, s)
      struct attr_desc *attr;
-     char *s;
+     const char *s;
 {
   if (attr->is_numeric)
     {
@@ -5339,13 +5353,14 @@ write_attr_value (attr, value)
 
 static void
 write_upcase (str)
-     char *str;
+     const char *str;
 {
   while (*str)
-    if (*str < 'a' || *str > 'z')
-      printf ("%c", *str++);
-    else
-      printf ("%c", *str++ - 'a' + 'A');
+  {
+    /* The argument of TOUPPER should not have side effects.  */
+    putchar (TOUPPER(*str));
+    str++;
+  }
 }
 
 static void
@@ -5398,7 +5413,7 @@ write_eligible_delay (kind)
   printf ("     rtx delay_insn;\n");
   printf ("     int slot;\n");
   printf ("     rtx candidate_insn;\n");
-  printf ("     int flags;\n");
+  printf ("     int flags ATTRIBUTE_UNUSED;\n");
   printf ("{\n");
   printf ("  rtx insn;\n");
   printf ("\n");
@@ -5571,6 +5586,7 @@ write_complex_function (unit, name, connection)
   int using_case;
   int i;
 
+  printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
   printf ("static int\n");
   printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
          unit->name, name);
@@ -5657,7 +5673,7 @@ write_complex_function (unit, name, connection)
 
 static int
 n_comma_elts (s)
-     char *s;
+     const char *s;
 {
   int n;
 
@@ -5677,10 +5693,10 @@ n_comma_elts (s)
 
 static char *
 next_comma_elt (pstr)
-     char **pstr;
+     const char **pstr;
 {
   char *out_str;
-  char *p;
+  const char *p;
 
   if (**pstr == '\0')
     return NULL;
@@ -5731,6 +5747,7 @@ find_attr (name, create)
   attr->name = attr_string (name, strlen (name));
   attr->first_value = attr->default_val = NULL;
   attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
+  attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
   attr->next = attrs[index];
   attrs[index] = attr;
 
@@ -5904,40 +5921,10 @@ copy_rtx_unchanging (orig)
 #endif
 }
 
-static void
-fatal VPROTO ((const char *format, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *format;
-#endif
-  va_list ap;
-
-  VA_START (ap, format);
-
-#ifndef ANSI_PROTOTYPES
-  format = va_arg (ap, const char *);
-#endif
-
-  fprintf (stderr, "genattrtab: ");
-  vfprintf (stderr, format, ap);
-  va_end (ap);
-  fprintf (stderr, "\n");
-  exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
-   config.h can #define abort fancy_abort if you like that sort of thing.  */
-
-void
-fancy_abort ()
-{
-  fatal ("Internal gcc abort.");
-}
-
 /* Determine if an insn has a constant number of delay slots, i.e., the
    number of delay slots is not a function of the length of the insn.  */
 
-void
+static void
 write_const_num_delay_slots ()
 {
   struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
@@ -5972,6 +5959,8 @@ write_const_num_delay_slots ()
 }
 
 \f
+extern int main PARAMS ((int, char **));
+
 int
 main (argc, argv)
      int argc;
@@ -5985,6 +5974,8 @@ main (argc, argv)
   rtx tem;
   int i;
 
+  progname = "genattrtab";
+
 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
   /* Get rid of any avoidable limit on stack size.  */
   {
@@ -5997,6 +5988,7 @@ main (argc, argv)
   }
 #endif
 
+  progname = "genattrtab";
   obstack_init (rtl_obstack);
   obstack_init (hash_obstack);
   obstack_init (temp_obstack);
@@ -6008,10 +6000,9 @@ main (argc, argv)
   if (infile == 0)
     {
       perror (argv[1]);
-      exit (FATAL_EXIT_CODE);
+      return (FATAL_EXIT_CODE);
     }
-
-  init_rtl ();
+  read_rtx_filename = argv[1];
 
   /* Set up true and false rtx's */
   true_rtx = rtx_alloc (CONST_INT);
@@ -6047,6 +6038,9 @@ from the machine description file `md'.  */\n\n");
       else if (GET_CODE (desc) == DEFINE_SPLIT)
        insn_code_number++, insn_index_number++;
 
+      else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
+       insn_code_number++, insn_index_number++;
+
       else if (GET_CODE (desc) == DEFINE_ATTR)
        {
          gen_attr (desc);
@@ -6085,6 +6079,7 @@ from the machine description file `md'.  */\n\n");
   printf ("#include \"config.h\"\n");
   printf ("#include \"system.h\"\n");
   printf ("#include \"rtl.h\"\n");
+  printf ("#include \"tm_p.h\"\n");
   printf ("#include \"insn-config.h\"\n");
   printf ("#include \"recog.h\"\n");
   printf ("#include \"regs.h\"\n");
@@ -6093,7 +6088,7 @@ from the machine description file `md'.  */\n\n");
   printf ("#include \"insn-attr.h\"\n");
   printf ("#include \"toplev.h\"\n");
   printf ("\n");  
-  printf ("#define operands recog_operand\n\n");
+  printf ("#define operands recog_data.operand\n\n");
 
   /* Make `insn_alternatives'.  */
   insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
@@ -6158,7 +6153,13 @@ from the machine description file `md'.  */\n\n");
   write_length_unit_log ();
 
   fflush (stdout);
-  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
-  /* NOTREACHED */
-  return 0;
+  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+}
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code ATTRIBUTE_UNUSED;
+{
+  return NULL;
 }