OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / gcc / genattrtab.c
index 287c69b..1a9ebd2 100644 (file)
@@ -1,13 +1,14 @@
 /* Generate code from machine description to compute values of attributes.
-   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GCC.
 
 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
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +17,8 @@ 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 GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This program handles insn attributes and the DEFINE_DELAY and
    DEFINE_INSN_RESERVATION definitions.
@@ -109,23 +109,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "coretypes.h"
 #include "tm.h"
 #include "rtl.h"
-#include "ggc.h"
 #include "gensupport.h"
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-/* 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"
 
-#include "genattrtab.h"
+/* Flags for make_internal_attr's `special' parameter.  */
+#define ATTR_NONE              0
+#define ATTR_SPECIAL           (1 << 0)
 
 static struct obstack obstack1, obstack2;
-struct obstack *hash_obstack = &obstack1;
-struct obstack *temp_obstack = &obstack2;
+static struct obstack *hash_obstack = &obstack1;
+static struct obstack *temp_obstack = &obstack2;
 
 /* enough space to reserve for printing out ints */
 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
@@ -142,7 +136,7 @@ struct insn_def
   struct insn_def *next;       /* Next insn in chain.  */
   rtx def;                     /* The DEFINE_...  */
   int insn_code;               /* Instruction number.  */
-  int insn_index;              /* Expression numer in file, for errors.  */
+  int insn_index;              /* Expression number in file, for errors.  */
   int lineno;                  /* Line number.  */
   int num_alternatives;                /* Number of alternatives.  */
   int vec_idx;                 /* Index of attribute vector in `def'.  */
@@ -183,7 +177,6 @@ struct attr_desc
   unsigned is_numeric  : 1;    /* Values of this attribute are numeric.  */
   unsigned is_const    : 1;    /* Attribute value constant for each run.  */
   unsigned is_special  : 1;    /* Don't call `write_attr_set'.  */
-  unsigned static_p    : 1;    /* Make the output function static.  */
 };
 
 /* Structure for each DEFINE_DELAY.  */
@@ -196,6 +189,14 @@ struct delay_desc
   int lineno;                  /* Line number.  */
 };
 
+struct attr_value_list
+{
+  struct attr_value *av;
+  struct insn_ent *ie;
+  struct attr_desc *attr;
+  struct attr_value_list *next;
+};
+
 /* Listheads of above structures.  */
 
 /* This one is indexed by the first character of the attribute name.  */
@@ -203,6 +204,7 @@ struct delay_desc
 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
 static struct insn_def *defs;
 static struct delay_desc *delays;
+struct attr_value_list **insn_code_values;
 
 /* Other variables.  */
 
@@ -217,8 +219,6 @@ static int num_delays;
 static int have_annul_true, have_annul_false;
 static int num_insn_ents;
 
-int num_dfa_decls;
-
 /* Stores, for each insn code, the number of constraint alternatives.  */
 
 static int *insn_n_alternatives;
@@ -240,16 +240,6 @@ static const char *delay_type_str;
 static const char *delay_1_0_str;
 static const char *num_delay_slots_str;
 
-/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
-   called.  */
-
-int reload_completed = 0;
-
-/* Some machines test `optimize' in macros called from rtlanal.c, so we need
-   to define it here.  */
-
-int optimize = 0;
-
 /* Simplify an expression.  Only call the routine if there is something to
    simplify.  */
 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)    \
@@ -258,90 +248,47 @@ int optimize = 0;
 
 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
 
-/* These are referenced by rtlanal.c and hence need to be defined somewhere.
-   They won't actually be used.  */
-
-rtx global_rtl[GR_MAX];
-rtx pic_offset_table_rtx;
-
-static void attr_hash_add_rtx  (int, rtx);
-static void attr_hash_add_string (int, char *);
-static rtx attr_rtx            (enum rtx_code, ...);
-static rtx attr_rtx_1          (enum rtx_code, va_list);
-static char *attr_string        (const char *, int);
-static rtx check_attr_value    (rtx, struct attr_desc *);
-static rtx convert_set_attr_alternative (rtx, struct insn_def *);
-static rtx convert_set_attr    (rtx, struct insn_def *);
-static void check_defs         (void);
-static rtx make_canonical      (struct attr_desc *, rtx);
-static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
-static rtx copy_rtx_unchanging (rtx);
-static rtx copy_boolean                (rtx);
-static void expand_delays      (void);
-static void fill_attr          (struct attr_desc *);
-static rtx substitute_address  (rtx, rtx (*) (rtx), rtx (*) (rtx));
-static void make_length_attrs  (void);
-static rtx identity_fn         (rtx);
-static rtx zero_fn             (rtx);
-static rtx one_fn              (rtx);
-static rtx max_fn              (rtx);
-static rtx min_fn              (rtx);
-static void write_length_unit_log (void);
-static rtx simplify_cond       (rtx, int, int);
-static void clear_struct_flag (rtx);
-static void remove_insn_ent  (struct attr_value *, struct insn_ent *);
-static void insert_insn_ent  (struct attr_value *, struct insn_ent *);
-static rtx insert_right_side   (enum rtx_code, rtx, rtx, int, int);
-static rtx make_alternative_compare (int);
-static int compute_alternative_mask (rtx, enum rtx_code);
-static rtx evaluate_eq_attr    (rtx, rtx, int, int);
-static rtx simplify_and_tree   (rtx, rtx *, int, int);
-static rtx simplify_or_tree    (rtx, rtx *, int, int);
-static rtx simplify_test_exp   (rtx, int, int);
-static rtx simplify_test_exp_in_temp (rtx, int, int);
-static void optimize_attrs     (void);
-static void gen_attr           (rtx, int);
-static int count_alternatives  (rtx);
-static int compares_alternatives_p (rtx);
-static int contained_in_p      (rtx, rtx);
-static void gen_insn           (rtx, int);
-static void gen_delay          (rtx, int);
-static void write_test_expr    (rtx, int);
-static int max_attr_value      (rtx, int*);
-static int min_attr_value      (rtx, int*);
-static int or_attr_value       (rtx, int*);
-static void walk_attr_value    (rtx);
-static void write_attr_get     (struct attr_desc *);
-static rtx eliminate_known_true (rtx, rtx, int, int);
-static void write_attr_set     (struct attr_desc *, int, rtx,
-                                const char *, const char *, rtx,
-                                int, int);
-static void write_insn_cases   (struct insn_ent *, int);
-static void write_attr_case    (struct attr_desc *, struct attr_value *,
-                                int, const char *, const char *, int, rtx);
-static void write_attr_valueq  (struct attr_desc *, const char *);
-static void write_attr_value   (struct attr_desc *, rtx);
-static void write_upcase       (const char *);
-static void write_indent       (int);
-static void write_eligible_delay (const char *);
-static int write_expr_attr_cache (rtx, struct attr_desc *);
-static void write_const_num_delay_slots (void);
-static char *next_comma_elt    (const char **);
+/* Forward declarations of functions used before their definitions, only.  */
+static char *attr_string           (const char *, int);
+static char *attr_printf           (unsigned int, const char *, ...)
+  ATTRIBUTE_PRINTF_2;
+static rtx make_numeric_value      (int);
 static struct attr_desc *find_attr (const char **, int);
-static struct attr_value *find_most_used  (struct attr_desc *);
-static rtx attr_eq             (const char *, const char *);
-static const char *attr_numeral        (int);
-static int attr_equal_p                (rtx, rtx);
-static rtx attr_copy_rtx       (rtx);
-static int attr_rtx_cost       (rtx);
-static bool attr_alt_subset_p (rtx, rtx);
+static rtx mk_attr_alt             (int);
+static char *next_comma_elt       (const char **);
+static rtx insert_right_side      (enum rtx_code, rtx, rtx, int, int);
+static rtx copy_boolean                   (rtx);
+static int compares_alternatives_p (rtx);
+static void make_internal_attr     (const char *, rtx, int);
+static void insert_insn_ent        (struct attr_value *, struct insn_ent *);
+static void walk_attr_value       (rtx);
+static int max_attr_value         (rtx, int*);
+static int min_attr_value         (rtx, int*);
+static int or_attr_value          (rtx, int*);
+static rtx simplify_test_exp      (rtx, int, int);
+static rtx simplify_test_exp_in_temp (rtx, int, int);
+static rtx copy_rtx_unchanging    (rtx);
+static bool attr_alt_subset_p      (rtx, rtx);
 static bool attr_alt_subset_of_compl_p (rtx, rtx);
-static rtx attr_alt_intersection (rtx, rtx);
-static rtx attr_alt_union (rtx, rtx);
-static rtx attr_alt_complement (rtx);
-static rtx mk_attr_alt (int);
-
-#define oballoc(size) obstack_alloc (hash_obstack, size)
+static void clear_struct_flag      (rtx);
+static void write_attr_valueq     (struct attr_desc *, const char *);
+static struct attr_value *find_most_used  (struct attr_desc *);
+static void write_attr_set        (struct attr_desc *, int, rtx,
+                                   const char *, const char *, rtx,
+                                   int, int);
+static void write_attr_case       (struct attr_desc *, struct attr_value *,
+                                   int, const char *, const char *, int, rtx);
+static void write_attr_value      (struct attr_desc *, rtx);
+static void write_upcase          (const char *);
+static void write_indent          (int);
+static rtx identity_fn            (rtx);
+static rtx zero_fn                (rtx);
+static rtx one_fn                 (rtx);
+static rtx max_fn                 (rtx);
+static rtx min_fn                 (rtx);
+
+#define oballoc(T) XOBNEW (hash_obstack, T)
+#define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
 
 /* Hash table for sharing RTL and strings.  */
 
@@ -368,11 +315,11 @@ struct attr_hash
    for each.  */
 
 #define RTL_HASH_SIZE 4093
-struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
+static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
 
 /* Here is how primitive or already-shared RTL's hash
    codes are made.  */
-#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
+#define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
 
 /* Add an entry to the hash table for RTL with hash code HASHCODE.  */
 
@@ -381,7 +328,7 @@ attr_hash_add_rtx (int hashcode, rtx rtl)
 {
   struct attr_hash *h;
 
-  h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
+  h = XOBNEW (hash_obstack, struct attr_hash);
   h->hashcode = hashcode;
   h->u.rtl = rtl;
   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
@@ -395,7 +342,7 @@ attr_hash_add_string (int hashcode, char *str)
 {
   struct attr_hash *h;
 
-  h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
+  h = XOBNEW (hash_obstack, struct attr_hash);
   h->hashcode = -hashcode;
   h->u.str = str;
   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
@@ -603,7 +550,7 @@ attr_rtx (enum rtx_code code, ...)
 
    rtx attr_printf (len, format, [arg1, ..., argn])  */
 
-char *
+static char *
 attr_printf (unsigned int len, const char *fmt, ...)
 {
   char str[256];
@@ -644,7 +591,7 @@ attr_string (const char *str, int len)
 
   /* Compute the hash code.  */
   hashcode = (len + 1) * 613 + (unsigned) str[0];
-  for (i = 1; i <= len; i += 2)
+  for (i = 1; i < len; i += 2)
     hashcode = ((hashcode * 613) + (unsigned) str[i]);
   if (hashcode < 0)
     hashcode = -hashcode;
@@ -656,7 +603,7 @@ attr_string (const char *str, int len)
       return h->u.str;                 /* <-- return if found.  */
 
   /* Not found; create a permanent copy and add it to the hash table.  */
-  new_str = obstack_alloc (hash_obstack, len + 1);
+  new_str = XOBNEWVAR (hash_obstack, char, len + 1);
   memcpy (new_str, str, len);
   new_str[len] = '\0';
   attr_hash_add_string (hashcode, new_str);
@@ -773,7 +720,7 @@ attr_copy_rtx (rtx orig)
 
    Return the new expression, if any.  */
 
-rtx
+static rtx
 check_attr_test (rtx exp, int is_const, int lineno)
 {
   struct attr_desc *attr;
@@ -1022,6 +969,7 @@ check_attr_value (rtx exp, struct attr_desc *attr)
     case CTZ:
     case POPCOUNT:
     case PARITY:
+    case BSWAP:
       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
       break;
 
@@ -1351,7 +1299,7 @@ get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
            || insn_alternatives[av->first_insn->def->insn_code]))
       return av;
 
-  av = oballoc (sizeof (struct attr_value));
+  av = oballoc (struct attr_value);
   av->value = value;
   av->next = attr->first_value;
   attr->first_value = av;
@@ -1494,7 +1442,7 @@ fill_attr (struct attr_desc *attr)
       else
        av = get_attr_value (value, attr, id->insn_code);
 
-      ie = oballoc (sizeof (struct insn_ent));
+      ie = oballoc (struct insn_ent);
       ie->def = id;
       insert_insn_ent (av, ie);
     }
@@ -1625,7 +1573,7 @@ make_length_attrs (void)
                                                         no_address_fn[i],
                                                         address_fn[i]),
                                     new_attr, ie->def->insn_code);
-           new_ie = oballoc (sizeof (struct insn_ent));
+           new_ie = oballoc (struct insn_ent);
            new_ie->def = ie->def;
            insert_insn_ent (new_av, new_ie);
          }
@@ -1690,7 +1638,7 @@ write_length_unit_log (void)
       for (length_unit_log = 0; length_or & 1; length_or >>= 1)
        length_unit_log++;
     }
-  printf ("const int length_unit_log = %u;\n", length_unit_log);
+  printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
 }
 
 /* Take a COND expression and see if any of the conditions in it can be
@@ -1710,7 +1658,7 @@ simplify_cond (rtx exp, int insn_code, int insn_index)
   rtx defval = XEXP (exp, 1);
   rtx new_defval = XEXP (exp, 1);
   int len = XVECLEN (exp, 0);
-  rtx *tests = xmalloc (len * sizeof (rtx));
+  rtx *tests = XNEWVEC (rtx, len);
   int allsame = 1;
   rtx ret;
 
@@ -1899,11 +1847,11 @@ insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int ins
 
   if (GET_CODE (exp) == code)
     {
-      rtx new = insert_right_side (code, XEXP (exp, 1),
-                                  term, insn_code, insn_index);
-      if (new != XEXP (exp, 1))
+      rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
+                                      term, insn_code, insn_index);
+      if (new_rtx != XEXP (exp, 1))
        /* Make a copy of this expression and call recursively.  */
-       newexp = attr_rtx (code, XEXP (exp, 0), new);
+       newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
       else
        newexp = exp;
     }
@@ -1993,22 +1941,22 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
       else
        newexp = false_rtx;
       break;
-      
+
     case SYMBOL_REF:
       {
        char *p;
        char string[256];
-       
+
        gcc_assert (GET_CODE (exp) == EQ_ATTR);
        gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
                    <= 256);
-       
+
        strcpy (string, XSTR (exp, 0));
        strcat (string, "_");
        strcat (string, XSTR (exp, 1));
        for (p = string; *p; p++)
          *p = TOUPPER (*p);
-       
+
        newexp = attr_rtx (EQ, value,
                           attr_rtx (SYMBOL_REF,
                                     DEF_ATTR_STRING (string)));
@@ -2019,12 +1967,12 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
       /* We construct an IOR of all the cases for which the
         requested attribute value is present.  Since we start with
         FALSE, if it is not present, FALSE will be returned.
-         
+
         Each case is the AND of the NOT's of the previous conditions with the
         current condition; in the default case the current condition is TRUE.
-         
+
         For each possible COND value, call ourselves recursively.
-         
+
         The extra TRUE and FALSE expressions will be eliminated by another
         call to the simplification routine.  */
 
@@ -2033,10 +1981,10 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
 
       for (i = 0; i < XVECLEN (value, 0); i += 2)
        {
-         rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
-                                               insn_code, insn_index);
+         rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
+                                                   insn_code, insn_index);
 
-         right = insert_right_side (AND, andexp, this,
+         right = insert_right_side (AND, andexp, this_cond,
                                     insn_code, insn_index);
          right = insert_right_side (AND, right,
                                     evaluate_eq_attr (exp,
@@ -2048,7 +1996,7 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
                                     insn_code, insn_index);
 
          /* Add this condition into the AND expression.  */
-         newexp = attr_rtx (NOT, this);
+         newexp = attr_rtx (NOT, this_cond);
          andexp = insert_right_side (AND, andexp, newexp,
                                      insn_code, insn_index);
        }
@@ -2160,7 +2108,7 @@ simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
 
       if (attr_alt_subset_p (exp, *pterm))
        *pterm = true_rtx;
-       
+
       return exp;
     }
 
@@ -2510,6 +2458,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index)
   struct attr_desc *attr;
   struct attr_value *av;
   struct insn_ent *ie;
+  struct attr_value_list *iv;
   int i;
   rtx newexp = exp;
   bool left_alt, right_alt;
@@ -2780,16 +2729,36 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index)
         would give this insn the values being tested for.  */
       if (insn_code >= 0
          && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
-       for (av = attr->first_value; av; av = av->next)
-         for (ie = av->first_insn; ie; ie = ie->next)
-           if (ie->def->insn_code == insn_code)
-             {
-               rtx x;
-               x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
-               x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
-               if (attr_rtx_cost(x) < 20)
-                 return x;
-             }
+       {
+         rtx x;
+
+         av = NULL;
+         if (insn_code_values)
+           {
+             for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
+               if (iv->attr == attr)
+                 {
+                   av = iv->av;
+                   break;
+                 }
+           }
+         else
+           {
+             for (av = attr->first_value; av; av = av->next)
+               for (ie = av->first_insn; ie; ie = ie->next)
+                 if (ie->def->insn_code == insn_code)
+                   goto got_av;
+           }
+
+         if (av)
+           {
+           got_av:
+             x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
+             x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
+             if (attr_rtx_cost(x) < 20)
+               return x;
+           }
+       }
       break;
 
     default:
@@ -2818,14 +2787,6 @@ optimize_attrs (void)
   struct insn_ent *ie;
   rtx newexp;
   int i;
-  struct attr_value_list
-  {
-    struct attr_value *av;
-    struct insn_ent *ie;
-    struct attr_desc *attr;
-    struct attr_value_list *next;
-  };
-  struct attr_value_list **insn_code_values;
   struct attr_value_list *ivbuf;
   struct attr_value_list *iv;
 
@@ -2836,13 +2797,12 @@ optimize_attrs (void)
     return;
 
   /* Make 2 extra elements, for "code" values -2 and -1.  */
-  insn_code_values = xcalloc ((insn_code_number + 2),
-                             sizeof (struct attr_value_list *));
+  insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
 
   /* Offset the table address so we can index by -2 or -1.  */
   insn_code_values += 2;
 
-  iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
+  iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
 
   for (i = 0; i < MAX_ATTRS_INDEX; i++)
     for (attr = attrs[i]; attr; attr = attr->next)
@@ -2903,6 +2863,7 @@ optimize_attrs (void)
 
   free (ivbuf);
   free (insn_code_values - 2);
+  insn_code_values = NULL;
 }
 
 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
@@ -2990,7 +2951,7 @@ gen_attr (rtx exp, int lineno)
       name_ptr = XSTR (exp, 1);
       while ((p = next_comma_elt (&name_ptr)) != NULL)
        {
-         av = oballoc (sizeof (struct attr_value));
+         av = oballoc (struct attr_value);
          av->value = attr_rtx (CONST_STRING, p);
          av->next = attr->first_value;
          attr->first_value = av;
@@ -3096,37 +3057,6 @@ compares_alternatives_p (rtx exp)
   return 0;
 }
 
-/* Returns nonzero is INNER is contained in EXP.  */
-
-static int
-contained_in_p (rtx inner, rtx exp)
-{
-  int i, j;
-  const char *fmt;
-
-  if (rtx_equal_p (inner, exp))
-    return 1;
-
-  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
-       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
-    switch (*fmt++)
-      {
-      case 'e':
-      case 'u':
-       if (contained_in_p (inner, XEXP (exp, i)))
-         return 1;
-       break;
-
-      case 'E':
-       for (j = 0; j < XVECLEN (exp, i); j++)
-         if (contained_in_p (inner, XVECEXP (exp, i, j)))
-           return 1;
-       break;
-      }
-
-  return 0;
-}
-
 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
 
 static void
@@ -3134,7 +3064,7 @@ gen_insn (rtx exp, int lineno)
 {
   struct insn_def *id;
 
-  id = oballoc (sizeof (struct insn_def));
+  id = oballoc (struct insn_def);
   id->next = defs;
   defs = id;
   id->def = exp;
@@ -3198,7 +3128,7 @@ gen_delay (rtx def, int lineno)
        have_annul_false = 1;
     }
 
-  delay = oballoc (sizeof (struct delay_desc));
+  delay = oballoc (struct delay_desc);
   delay->def = def;
   delay->num = ++num_delays;
   delay->next = delays;
@@ -3393,7 +3323,7 @@ write_test_expr (rtx exp, int flags)
            }
          else
            {
-             printf ("%s((1 << which_alternative) & 0x%x)",
+             printf ("%s((1 << which_alternative) & %#x)",
                      XINT (exp, 1) ? "!" : "", set);
            }
        }
@@ -3711,8 +3641,6 @@ write_attr_get (struct attr_desc *attr)
 
   /* Write out start of function, then all values with explicit `case' lines,
      then a `default', then the value with the most uses.  */
-  if (attr->static_p)
-    printf ("static ");
   if (!attr->is_numeric)
     printf ("enum attr_%s\n", attr->name);
   else
@@ -3954,51 +3882,6 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av,
   printf ("\n");
 }
 
-/* Search for uses of non-const attributes and write code to cache them.  */
-
-static int
-write_expr_attr_cache (rtx p, struct attr_desc *attr)
-{
-  const char *fmt;
-  int i, ie, j, je;
-
-  if (GET_CODE (p) == EQ_ATTR)
-    {
-      if (XSTR (p, 0) != attr->name)
-       return 0;
-
-      if (!attr->is_numeric)
-       printf ("  enum attr_%s ", attr->name);
-      else
-       printf ("  int ");
-
-      printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
-      return 1;
-    }
-
-  fmt = GET_RTX_FORMAT (GET_CODE (p));
-  ie = GET_RTX_LENGTH (GET_CODE (p));
-  for (i = 0; i < ie; i++)
-    {
-      switch (*fmt++)
-       {
-       case 'e':
-         if (write_expr_attr_cache (XEXP (p, i), attr))
-           return 1;
-         break;
-
-       case 'E':
-         je = XVECLEN (p, i);
-         for (j = 0; j < je; ++j)
-           if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
-             return 1;
-         break;
-       }
-    }
-
-  return 0;
-}
-
 /* Utilities to write in various forms.  */
 
 static void
@@ -4011,7 +3894,7 @@ write_attr_valueq (struct attr_desc *attr, const char *s)
       printf ("%d", num);
 
       if (num > 9 || num < 0)
-       printf (" /* 0x%x */", num);
+       printf (" /* %#x */", num);
     }
   else
     {
@@ -4277,11 +4160,10 @@ find_attr (const char **name_p, int create)
   if (! create)
     return NULL;
 
-  attr = oballoc (sizeof (struct attr_desc));
+  attr = oballoc (struct attr_desc);
   attr->name = DEF_ATTR_STRING (name);
   attr->first_value = attr->default_val = NULL;
   attr->is_numeric = attr->is_const = attr->is_special = 0;
-  attr->static_p = 0;
   attr->next = attrs[index];
   attrs[index] = attr;
 
@@ -4292,7 +4174,7 @@ find_attr (const char **name_p, int create)
 
 /* Create internal attribute with the given default value.  */
 
-void
+static void
 make_internal_attr (const char *name, rtx value, int special)
 {
   struct attr_desc *attr;
@@ -4303,7 +4185,6 @@ make_internal_attr (const char *name, rtx value, int special)
   attr->is_numeric = 1;
   attr->is_const = 0;
   attr->is_special = (special & ATTR_SPECIAL) != 0;
-  attr->static_p = (special & ATTR_STATIC) != 0;
   attr->default_val = get_attr_value (value, attr, -2);
 }
 
@@ -4328,7 +4209,7 @@ find_most_used (struct attr_desc *attr)
 
 /* Return (attr_value "n") */
 
-rtx
+static rtx
 make_numeric_value (int n)
 {
   static rtx int_values[20];
@@ -4388,6 +4269,171 @@ write_const_num_delay_slots (void)
       printf ("    }\n}\n\n");
     }
 }
+\f
+/* Synthetic attributes used by insn-automata.c and the scheduler.
+   These are primarily concerned with (define_insn_reservation)
+   patterns.  */
+
+struct insn_reserv
+{
+  struct insn_reserv *next;
+
+  const char *name;
+  int default_latency;
+  rtx condexp;
+
+  /* Sequence number of this insn.  */
+  int insn_num;
+
+  /* Whether a (define_bypass) construct names this insn in its
+     output list.  */
+  bool bypassed;
+};
+
+static struct insn_reserv *all_insn_reservs = 0;
+static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
+static size_t n_insn_reservs;
+
+/* Store information from a DEFINE_INSN_RESERVATION for future
+   attribute generation.  */
+static void
+gen_insn_reserv (rtx def)
+{
+  struct insn_reserv *decl = oballoc (struct insn_reserv);
+
+  decl->name            = DEF_ATTR_STRING (XSTR (def, 0));
+  decl->default_latency = XINT (def, 1);
+  decl->condexp         = check_attr_test (XEXP (def, 2), 0, 0);
+  decl->insn_num        = n_insn_reservs;
+  decl->bypassed       = false;
+  decl->next            = 0;
+
+  *last_insn_reserv_p = decl;
+  last_insn_reserv_p  = &decl->next;
+  n_insn_reservs++;
+}
+
+/* Store information from a DEFINE_BYPASS for future attribute
+   generation.  The only thing we care about is the list of output
+   insns, which will later be used to tag reservation structures with
+   a 'bypassed' bit.  */
+
+struct bypass_list
+{
+  struct bypass_list *next;
+  const char *insn;
+};
+
+static struct bypass_list *all_bypasses;
+static size_t n_bypasses;
+
+static void
+gen_bypass_1 (const char *s, size_t len)
+{
+  struct bypass_list *b;
+
+  if (len == 0)
+    return;
+
+  s = attr_string (s, len);
+  for (b = all_bypasses; b; b = b->next)
+    if (s == b->insn)
+      return;  /* already got that one */
+
+  b = oballoc (struct bypass_list);
+  b->insn = s;
+  b->next = all_bypasses;
+  all_bypasses = b;
+  n_bypasses++;
+}
+
+static void
+gen_bypass (rtx def)
+{
+  const char *p, *base;
+
+  for (p = base = XSTR (def, 1); *p; p++)
+    if (*p == ',')
+      {
+       gen_bypass_1 (base, p - base);
+       do
+         p++;
+       while (ISSPACE (*p));
+       base = p;
+      }
+  gen_bypass_1 (base, p - base);
+}
+
+/* Find and mark all of the bypassed insns.  */
+static void
+process_bypasses (void)
+{
+  struct bypass_list *b;
+  struct insn_reserv *r;
+
+  /* The reservation list is likely to be much longer than the bypass
+     list.  */
+  for (r = all_insn_reservs; r; r = r->next)
+    for (b = all_bypasses; b; b = b->next)
+      if (r->name == b->insn)
+       r->bypassed = true;
+}
+
+/* Create all of the attributes that describe automaton properties.  */
+static void
+make_automaton_attrs (void)
+{
+  int i;
+  struct insn_reserv *decl;
+  rtx code_exp, lats_exp, byps_exp;
+
+  if (n_insn_reservs == 0)
+    return;
+
+  code_exp = rtx_alloc (COND);
+  lats_exp = rtx_alloc (COND);
+
+  XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+  XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+
+  XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
+  XEXP (lats_exp, 1) = make_numeric_value (0);
+
+  for (decl = all_insn_reservs, i = 0;
+       decl;
+       decl = decl->next, i += 2)
+    {
+      XVECEXP (code_exp, 0, i)   = decl->condexp;
+      XVECEXP (lats_exp, 0, i)   = decl->condexp;
+
+      XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
+      XVECEXP (lats_exp, 0, i+1) = make_numeric_value (decl->default_latency);
+    }
+
+  if (n_bypasses == 0)
+    byps_exp = make_numeric_value (0);
+  else
+    {
+      process_bypasses ();
+
+      byps_exp = rtx_alloc (COND);
+      XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
+      XEXP (byps_exp, 1) = make_numeric_value (0);
+      for (decl = all_insn_reservs, i = 0;
+          decl;
+          decl = decl->next)
+       if (decl->bypassed)
+         {
+           XVECEXP (byps_exp, 0, i)   = decl->condexp;
+           XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
+           i += 2;
+         }
+    }
+
+  make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
+  make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
+  make_internal_attr ("*bypass_p",               byps_exp, ATTR_NONE);
+}
 
 int
 main (int argc, char **argv)
@@ -4425,7 +4471,6 @@ from the machine description file `md'.  */\n\n");
 
   /* Read the machine description.  */
 
-  initiate_automaton_gen (argc, argv);
   while (1)
     {
       int lineno;
@@ -4450,54 +4495,14 @@ from the machine description file `md'.  */\n\n");
          gen_delay (desc, lineno);
          break;
 
-       case DEFINE_CPU_UNIT:
-         gen_cpu_unit (desc);
-         break;
-
-       case DEFINE_QUERY_CPU_UNIT:
-         gen_query_cpu_unit (desc);
+       case DEFINE_INSN_RESERVATION:
+         gen_insn_reserv (desc);
          break;
 
        case DEFINE_BYPASS:
          gen_bypass (desc);
          break;
 
-       case EXCLUSION_SET:
-         gen_excl_set (desc);
-         break;
-
-       case PRESENCE_SET:
-         gen_presence_set (desc);
-         break;
-
-       case FINAL_PRESENCE_SET:
-         gen_final_presence_set (desc);
-         break;
-
-       case ABSENCE_SET:
-         gen_absence_set (desc);
-         break;
-
-       case FINAL_ABSENCE_SET:
-         gen_final_absence_set (desc);
-         break;
-
-       case DEFINE_AUTOMATON:
-         gen_automaton (desc);
-         break;
-
-       case AUTOMATA_OPTION:
-         gen_automata_option (desc);
-         break;
-
-       case DEFINE_RESERVATION:
-         gen_reserv (desc);
-         break;
-
-       case DEFINE_INSN_RESERVATION:
-         gen_insn_reserv (desc);
-         break;
-
        default:
          break;
        }
@@ -4522,23 +4527,17 @@ from the machine description file `md'.  */\n\n");
   if (num_delays)
     expand_delays ();
 
-  /* Build DFA, output some functions and expand DFA information
-     to new attributes.  */
-  if (num_dfa_decls)
-    expand_automata ();
-
   printf ("#include \"config.h\"\n");
   printf ("#include \"system.h\"\n");
   printf ("#include \"coretypes.h\"\n");
   printf ("#include \"tm.h\"\n");
   printf ("#include \"rtl.h\"\n");
+  printf ("#include \"insn-attr.h\"\n");
   printf ("#include \"tm_p.h\"\n");
   printf ("#include \"insn-config.h\"\n");
   printf ("#include \"recog.h\"\n");
   printf ("#include \"regs.h\"\n");
-  printf ("#include \"real.h\"\n");
   printf ("#include \"output.h\"\n");
-  printf ("#include \"insn-attr.h\"\n");
   printf ("#include \"toplev.h\"\n");
   printf ("#include \"flags.h\"\n");
   printf ("#include \"function.h\"\n");
@@ -4546,17 +4545,20 @@ from the machine description file `md'.  */\n\n");
   printf ("#define operands recog_data.operand\n\n");
 
   /* Make `insn_alternatives'.  */
-  insn_alternatives = oballoc (insn_code_number * sizeof (int));
+  insn_alternatives = oballocvec (int, insn_code_number);
   for (id = defs; id; id = id->next)
     if (id->insn_code >= 0)
       insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
 
   /* Make `insn_n_alternatives'.  */
-  insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
+  insn_n_alternatives = oballocvec (int, insn_code_number);
   for (id = defs; id; id = id->next)
     if (id->insn_code >= 0)
       insn_n_alternatives[id->insn_code] = id->num_alternatives;
 
+  /* Construct extra attributes for automata.  */
+  make_automaton_attrs ();
+
   /* Prepare to write out attribute subroutines by checking everything stored
      away and building the attribute cases.  */
 
@@ -4587,18 +4589,7 @@ from the machine description file `md'.  */\n\n");
     for (attr = attrs[i]; attr; attr = attr->next)
       {
        if (! attr->is_special && ! attr->is_const)
-         {
-           int insn_alts_p;
-
-           insn_alts_p
-             = (attr->name [0] == '*'
-                && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
-           if (insn_alts_p)
-             printf ("\n#if AUTOMATON_ALTS\n");
-           write_attr_get (attr);
-           if (insn_alts_p)
-             printf ("#endif\n\n");
-         }
+         write_attr_get (attr);
       }
 
   /* Write out delay eligibility information, if DEFINE_DELAY present.
@@ -4613,11 +4604,6 @@ from the machine description file `md'.  */\n\n");
        write_eligible_delay ("annul_false");
     }
 
-  /* Output code for pipeline hazards recognition based on DFA
-     (deterministic finite-state automata).  */
-  if (num_dfa_decls)
-    write_automata ();
-
   /* Write out constant delay slot info.  */
   write_const_num_delay_slots ();