OSDN Git Service

* expr.c (expand_expr): Use gen_int_mode for the argument
[pf3gnuchains/gcc-fork.git] / gcc / genattrtab.c
index 071dd54..0270945 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 GCC.
@@ -86,17 +86,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    definitions (each would be accessed through a pointer).
 
    We use the flags in an RTX as follows:
-   `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
+   `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
       independent of the insn code.
-   `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
+   `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
       for the insn code currently being processed (see optimize_attrs).
-   `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
+   `integrated' (ATTR_PERMANENT_P): This rtx is permanent and unique
       (see attr_rtx).
-   `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
+   `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
       EQ_ATTR rtx is true if !volatil and false if volatil.  */
 
-#include "hconfig.h"
+#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
+#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
+#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), integrated))
+#define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
+
+#include "bconfig.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "ggc.h"
 #include "gensupport.h"
@@ -110,13 +117,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "obstack.h"
 #include "errors.h"
 
+#include "genattrtab.h"
+
 static struct obstack obstack1, obstack2;
 struct obstack *hash_obstack = &obstack1;
 struct obstack *temp_obstack = &obstack2;
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
 /* enough space to reserve for printing out ints */
 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
 
@@ -231,7 +237,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.  */
@@ -262,7 +268,7 @@ static struct function_unit *units;
 
    The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
    expression are the same, the will also have the same address.  We find
-   all the EQ_ATTR nodes by marking them MEM_VOLATILE_P.  This bit later
+   all the EQ_ATTR nodes by marking them ATTR_EQ_ATTR_P.  This bit later
    represents the value of an EQ_ATTR node, so once all nodes are marked,
    they are also given an initial value of FALSE.
 
@@ -304,6 +310,8 @@ static int have_annul_true, have_annul_false;
 static int num_units, num_unit_opclasses;
 static int num_insn_ents;
 
+int num_dfa_decls;
+
 /* Used as operand to `operate_exp':  */
 
 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
@@ -344,7 +352,7 @@ 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)    \
-  (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP)     \
+  (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
 
 /* Simplify (eq_attr ("alternative") ...)
@@ -365,10 +373,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 ((unsigned int, const char *, ...))
-  ATTRIBUTE_PRINTF_2;
+static rtx attr_rtx_1          PARAMS ((enum rtx_code, va_list));
 static char *attr_string        PARAMS ((const char *, int));
-static rtx check_attr_test     PARAMS ((rtx, int, int));
 static rtx check_attr_value    PARAMS ((rtx, struct attr_desc *));
 static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
 static rtx convert_set_attr    PARAMS ((rtx, struct insn_def *));
@@ -386,7 +392,6 @@ 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  PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
 static void make_length_attrs  PARAMS ((void));
 static rtx identity_fn         PARAMS ((rtx));
@@ -449,13 +454,10 @@ static void write_complex_function PARAMS ((struct function_unit *, const char *
 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));
@@ -503,7 +505,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));
@@ -520,7 +522,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));
@@ -531,35 +533,25 @@ attr_hash_add_string (hashcode, str)
 }
 
 /* Generate an RTL expression, but avoid duplicates.
-   Set the RTX_INTEGRATED_P flag for these permanent objects.
+   Set the ATTR_PERMANENT_P flag for these permanent objects.
 
    In some cases we cannot uniquify; then we return an ordinary
-   impermanent rtx with RTX_INTEGRATED_P clear.
+   impermanent rtx with ATTR_PERMANENT_P clear.
 
    Args are like gen_rtx, but without the mode:
 
    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.  */
@@ -569,11 +561,10 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
       rtx arg0 = va_arg (p, rtx);
 
       /* A permanent object cannot point to impermanent ones.  */
-      if (! RTX_INTEGRATED_P (arg0))
+      if (! ATTR_PERMANENT_P (arg0))
        {
          rt_val = rtx_alloc (code);
          XEXP (rt_val, 0) = arg0;
-         va_end (p);
          return rt_val;
        }
 
@@ -582,7 +573,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)
        {
@@ -599,12 +590,11 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
       rtx arg1 = va_arg (p, rtx);
 
       /* A permanent object cannot point to impermanent ones.  */
-      if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
+      if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
        {
          rt_val = rtx_alloc (code);
          XEXP (rt_val, 0) = arg0;
          XEXP (rt_val, 1) = arg1;
-         va_end (p);
          return rt_val;
        }
 
@@ -614,7 +604,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)
        {
@@ -637,7 +627,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)
        {
@@ -659,7 +649,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)
        {
@@ -673,19 +663,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.  */
 
@@ -722,19 +709,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;
+  ATTR_PERMANENT_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,8 +735,8 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
 
    rtx attr_printf (len, format, [arg1, ..., argn])  */
 
-static char *
-attr_printf VPARAMS ((register unsigned int len, const char *fmt, ...))
+char *
+attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
 {
   char str[256];
 
@@ -751,7 +744,7 @@ attr_printf VPARAMS ((register unsigned int len, const char *fmt, ...))
   VA_FIXEDARG (p, unsigned int, len);
   VA_FIXEDARG (p, const char *, fmt);
   
-  if (len > sizeof str - 1) /* leave room for \0. */
+  if (len > sizeof str - 1) /* Leave room for \0.  */
     abort ();
 
   vsprintf (str, fmt, p);
@@ -783,10 +776,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];
@@ -818,7 +811,7 @@ static int
 attr_equal_p (x, y)
      rtx x, y;
 {
-  return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
+  return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
                     && rtx_equal_p (x, y)));
 }
 \f
@@ -828,15 +821,15 @@ 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))
+  if (ATTR_PERMANENT_P (orig))
     return orig;
 
   code = GET_CODE (orig);
@@ -847,6 +840,7 @@ attr_copy_rtx (orig)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -859,10 +853,10 @@ attr_copy_rtx (orig)
 
   copy = rtx_alloc (code);
   PUT_MODE (copy, GET_MODE (orig));
-  copy->in_struct = orig->in_struct;
-  copy->volatil = orig->volatil;
-  copy->unchanging = orig->unchanging;
-  copy->integrated = orig->integrated;
+  ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
+  ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
+  ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
+  ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
 
   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
 
@@ -920,9 +914,9 @@ 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
+rtx
 check_attr_test (exp, is_const, lineno)
      rtx exp;
      int is_const;
@@ -952,15 +946,15 @@ check_attr_test (exp, is_const, lineno)
                {
                  XSTR (exp, 0) = alternative_name;
                  /* This can't be simplified any further.  */
-                 RTX_UNCHANGING_P (exp) = 1;
+                 ATTR_IND_SIMPLIFIED_P (exp) = 1;
                  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,
@@ -971,13 +965,13 @@ check_attr_test (exp, is_const, lineno)
             constant attribute, so don't expand this until it's time to
             write the test expression.  */
          if (attr->is_const)
-           RTX_UNCHANGING_P (exp) = 1;
+           ATTR_IND_SIMPLIFIED_P (exp) = 1;
 
          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
@@ -988,7 +982,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));
            }
        }
@@ -1033,7 +1027,7 @@ check_attr_test (exp, is_const, lineno)
        fatal ("RTL operator \"%s\" not valid in constant attribute test",
               GET_RTX_NAME (GET_CODE (exp)));
       /* These cases can't be simplified.  */
-      RTX_UNCHANGING_P (exp) = 1;
+      ATTR_IND_SIMPLIFIED_P (exp) = 1;
       break;
 
     case LE:  case LT:  case GT:  case GE:
@@ -1045,7 +1039,7 @@ check_attr_test (exp, is_const, lineno)
                        attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
                        attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
       /* These cases can't be simplified.  */
-      RTX_UNCHANGING_P (exp) = 1;
+      ATTR_IND_SIMPLIFIED_P (exp) = 1;
       break;
 
     case SYMBOL_REF:
@@ -1054,7 +1048,7 @@ check_attr_test (exp, is_const, lineno)
          /* These cases are valid for constant attributes, but can't be
             simplified.  */
          exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
-         RTX_UNCHANGING_P (exp) = 1;
+         ATTR_IND_SIMPLIFIED_P (exp) = 1;
          break;
        }
     default:
@@ -1112,7 +1106,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",
@@ -1167,6 +1161,10 @@ check_attr_value (exp, attr)
       break;
 
     case FFS:
+    case CLZ:
+    case CTZ:
+    case POPCOUNT:
+    case PARITY:
       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
       break;
 
@@ -1412,7 +1410,7 @@ convert_const_symbol_ref (exp, attr)
        *p = TOUPPER (*p);
 
       value = attr_rtx (SYMBOL_REF, string);
-      RTX_UNCHANGING_P (value) = 1;
+      ATTR_IND_SIMPLIFIED_P (value) = 1;
 
       XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
 
@@ -1446,25 +1444,25 @@ 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;
        }
 
       break;
 
     case SYMBOL_REF:
-      if (!attr->is_const || RTX_UNCHANGING_P (exp))
+      if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
        break;
       /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
         This makes the COND something that won't be considered an arbitrary
         expression by walk_attr_value.  */
-      RTX_UNCHANGING_P (exp) = 1;
+      ATTR_IND_SIMPLIFIED_P (exp) = 1;
 #if 0
       /* ??? Why do we do this?  With attribute values { A B C D E }, this
          tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
         than (x==E).  */
       exp = convert_const_symbol_ref (exp, attr);
-      RTX_UNCHANGING_P (exp) = 1;
+      ATTR_IND_SIMPLIFIED_P (exp) = 1;
       exp = check_attr_value (exp, attr);
       /* Goto COND case since this is now a COND.  Note that while the
          new expression is rescanned, all symbol_ref notes are marked as
@@ -1783,7 +1781,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
@@ -1835,7 +1833,7 @@ operate_exp (op, left, right)
     }
 
   else
-    fatal ("Badly formed attribute value.");
+    fatal ("badly formed attribute value");
   /* NOTREACHED */
   return NULL;
 }
@@ -1846,7 +1844,7 @@ operate_exp (op, left, right)
    The first produces a function `function_units_used' which is given an
    insn and produces an encoding showing which function units are required
    for the execution of that insn.  If the value is non-negative, the insn
-   uses that unit; otherwise, the value is a one's compliment mask of units
+   uses that unit; otherwise, the value is a one's complement mask of units
    used.
 
    The second produces a function `result_ready_cost' which is used to
@@ -2091,7 +2089,7 @@ expand_units ()
             every possible C.
 
             The issue delay function for C is op->issue_exp and is used to
-            write the `<name>_unit_conflict_cost' function.  Symbolicly
+            write the `<name>_unit_conflict_cost' function.  Symbolically
             this is "ISSUE-DELAY (E,C)".
 
             The pipeline delay results form the FIFO constraint on the
@@ -2101,7 +2099,7 @@ expand_units ()
             fill the unit given the minimum issue delay.  FILL-TIME is the
             constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
             the simultaneity constraint is "READY-COST (E) - FILL-TIME"
-            if SIMULTANEITY is non-zero and zero otherwise.
+            if SIMULTANEITY is nonzero and zero otherwise.
 
             Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
 
@@ -2254,16 +2252,16 @@ simplify_knowing (exp, known_true)
 /* Translate the CONST_STRING expressions in X to change the encoding of
    value.  On input, the value is a bitmask with a one bit for each unit
    used; on output, the value is the unit number (zero based) if one
-   and only one unit is used or the one's compliment of the bitmask.  */
+   and only one unit is used or the one's complement of the bitmask.  */
 
 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);
 
@@ -2272,7 +2270,7 @@ encode_units_mask (x)
     case CONST_STRING:
       i = atoi (XSTR (x, 0));
       if (i < 0)
-       /* The sign bit encodes a one's compliment mask.  */
+       /* The sign bit encodes a one's complement mask.  */
        abort ();
       else if (i != 0 && i == (i & -i))
        /* Only one bit is set, so yield that unit number.  */
@@ -2286,6 +2284,7 @@ encode_units_mask (x)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -2448,8 +2447,8 @@ make_length_attrs ()
   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;
@@ -2462,7 +2461,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;
@@ -2569,11 +2568,10 @@ simplify_cond (exp, insn_code, insn_index)
   int len = XVECLEN (exp, 0);
   rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
   int allsame = 1;
-  char *first_spacer;
   rtx ret;
 
   /* This lets us free all storage allocated below, if appropriate.  */
-  first_spacer = (char *) obstack_finish (rtl_obstack);
+  obstack_finish (rtl_obstack);
 
   memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
 
@@ -2830,7 +2828,7 @@ make_alternative_compare (mask)
     ;
 
   newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
-  RTX_UNCHANGING_P (newexp) = 1;
+  ATTR_IND_SIMPLIFIED_P (newexp) = 1;
 
   return newexp;
 }
@@ -2938,7 +2936,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
     abort ();
 
   /* If uses an address, must return original expression.  But set the
-     RTX_UNCHANGING_P bit so we don't try to simplify it again.  */
+     ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again.  */
 
   address_used = 0;
   walk_attr_value (newexp);
@@ -2946,7 +2944,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
   if (address_used)
     {
       /* This had `&& current_alternative_string', which seems to be wrong.  */
-      if (! RTX_UNCHANGING_P (exp))
+      if (! ATTR_IND_SIMPLIFIED_P (exp))
        return copy_rtx_unchanging (exp);
       return exp;
     }
@@ -3155,7 +3153,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;
@@ -3204,8 +3202,8 @@ attr_rtx_cost (x)
 \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.  */
+   memory bloat.  Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
+   and avoid unnecessary copying if possible.  */
 
 static rtx
 simplify_test_exp_in_temp (exp, insn_code, insn_index)
@@ -3214,7 +3212,7 @@ simplify_test_exp_in_temp (exp, insn_code, insn_index)
 {
   rtx x;
   struct obstack *old;
-  if (RTX_UNCHANGING_P (exp))
+  if (ATTR_IND_SIMPLIFIED_P (exp))
     return exp;
   old = rtl_obstack;
   rtl_obstack = temp_obstack;
@@ -3247,7 +3245,7 @@ simplify_test_exp (exp, insn_code, insn_index)
   rtx newexp = exp;
 
   /* Don't re-simplify something we already simplified.  */
-  if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
+  if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
     return exp;
 
   switch (GET_CODE (exp))
@@ -3313,7 +3311,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.  */
@@ -3397,7 +3395,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.  */
@@ -3474,7 +3472,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)
@@ -3497,7 +3495,7 @@ simplify_test_exp (exp, insn_code, insn_index)
      won't buy anything unless we weren't given a valid insn code
      to process (i.e., we are canonicalizing something.).  */
   if (insn_code != -2 /* Seems wrong: && current_alternative_string.  */
-      && ! RTX_UNCHANGING_P (newexp))
+      && ! ATTR_IND_SIMPLIFIED_P (newexp))
     return copy_rtx_unchanging (newexp);
 
   return newexp;
@@ -3565,7 +3563,7 @@ optimize_attrs ()
   /* Process one insn code at a time.  */
   for (i = -2; i < insn_code_number; i++)
     {
-      /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
+      /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
         We use it to mean "already simplified for this insn".  */
       for (iv = insn_code_values[i]; iv; iv = iv->next)
        clear_struct_flag (iv->av->value);
@@ -3753,13 +3751,13 @@ simplify_by_exploding (exp)
   most_tests = -1;
   for (i = num_marks = 0; i < total; i++)
     if (GET_CODE (condval[i]) == CONST_STRING
-       && ! MEM_VOLATILE_P (condval[i]))
+       && ! ATTR_EQ_ATTR_P (condval[i]))
       {
        /* Mark the unmarked constant value and count how many are marked.  */
-       MEM_VOLATILE_P (condval[i]) = 1;
+       ATTR_EQ_ATTR_P (condval[i]) = 1;
        for (j = new_marks = 0; j < total; j++)
          if (GET_CODE (condval[j]) == CONST_STRING
-             && MEM_VOLATILE_P (condval[j]))
+             && ATTR_EQ_ATTR_P (condval[j]))
            new_marks++;
        if (new_marks - num_marks > most_tests)
          {
@@ -3770,7 +3768,7 @@ simplify_by_exploding (exp)
       }
   /* Clear all the marks.  */
   for (i = 0; i < total; i++)
-    MEM_VOLATILE_P (condval[i]) = 0;
+    ATTR_EQ_ATTR_P (condval[i]) = 0;
 
   /* Give up if nothing is constant.  */
   if (num_marks == 0)
@@ -3802,7 +3800,7 @@ simplify_by_exploding (exp)
   return ret;
 }
 
-/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
+/* Set the ATTR_EQ_ATTR_P flag for all EQ_ATTR expressions in EXP and
    verify that EXP can be simplified to a constant term if all the EQ_ATTR
    tests have known value.  */
 
@@ -3816,14 +3814,14 @@ find_and_mark_used_attributes (exp, terms, nterms)
   switch (GET_CODE (exp))
     {
     case EQ_ATTR:
-      if (! MEM_VOLATILE_P (exp))
+      if (! ATTR_EQ_ATTR_P (exp))
        {
          rtx link = rtx_alloc (EXPR_LIST);
          XEXP (link, 0) = exp;
          XEXP (link, 1) = *terms;
          *terms = link;
          *nterms += 1;
-         MEM_VOLATILE_P (exp) = 1;
+         ATTR_EQ_ATTR_P (exp) = 1;
        }
       return 1;
 
@@ -3856,7 +3854,7 @@ find_and_mark_used_attributes (exp, terms, nterms)
     }
 }
 
-/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
+/* Clear the ATTR_EQ_ATTR_P flag in all EQ_ATTR expressions on LIST and
    in the values of the NDIM-dimensional attribute space SPACE.  */
 
 static void
@@ -3875,7 +3873,7 @@ unmark_used_attributes (list, space, ndim)
     {
       exp = XEXP (link, 0);
       if (GET_CODE (exp) == EQ_ATTR)
-       MEM_VOLATILE_P (exp) = 0;
+       ATTR_EQ_ATTR_P (exp) = 0;
     }
 }
 
@@ -3911,7 +3909,7 @@ add_values_to_cover (dim)
        if (GET_CODE (av->value) == CONST_STRING)
          {
            exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
-           if (MEM_VOLATILE_P (exp))
+           if (ATTR_EQ_ATTR_P (exp))
              continue;
 
            link = rtx_alloc (EXPR_LIST);
@@ -4001,7 +3999,7 @@ simplify_with_current_value (exp, space, ndim)
     {
       x = XEXP (space[i].current_value, 0);
       if (GET_CODE (x) == EQ_ATTR)
-       MEM_VOLATILE_P (x) = 0;
+       ATTR_EQ_ATTR_P (x) = 0;
     }
 
   exp = simplify_with_current_value_aux (exp);
@@ -4011,26 +4009,26 @@ simplify_with_current_value (exp, space, ndim)
     {
       x = XEXP (space[i].current_value, 0);
       if (GET_CODE (x) == EQ_ATTR)
-       MEM_VOLATILE_P (x) = 1;
+       ATTR_EQ_ATTR_P (x) = 1;
     }
 
   return exp;
 }
 
-/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
+/* Reduce the expression EXP based on the ATTR_EQ_ATTR_P settings of
    all EQ_ATTR expressions.  */
 
 static rtx
 simplify_with_current_value_aux (exp)
      rtx exp;
 {
-  register int i;
+  int i;
   rtx cond;
 
   switch (GET_CODE (exp))
     {
     case EQ_ATTR:
-      if (MEM_VOLATILE_P (exp))
+      if (ATTR_EQ_ATTR_P (exp))
        return false_rtx;
       else
        return true_rtx;
@@ -4097,19 +4095,19 @@ simplify_with_current_value_aux (exp)
     }
 }
 \f
-/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions.  */
+/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
 
 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))
+  ATTR_CURR_SIMPLIFIED_P (x) = 0;
+  if (ATTR_IND_SIMPLIFIED_P (x))
     return;
 
   code = GET_CODE (x);
@@ -4120,6 +4118,7 @@ clear_struct_flag (x)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4161,10 +4160,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);
@@ -4175,6 +4174,7 @@ count_sub_rtxs (x, max)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4320,7 +4320,7 @@ count_alternatives (exp)
   return 0;
 }
 \f
-/* Returns non-zero if the given expression contains an EQ_ATTR with the
+/* Returns nonzero if the given expression contains an EQ_ATTR with the
    `alternative' attribute.  */
 
 static int
@@ -4353,7 +4353,7 @@ compares_alternatives_p (exp)
   return 0;
 }
 \f
-/* Returns non-zero is INNER is contained in EXP.  */
+/* Returns nonzero is INNER is contained in EXP.  */
 
 static int
 contained_in_p (inner, exp)
@@ -4563,7 +4563,7 @@ gen_unit (def, lineno)
 /* Given a piece of RTX, print a C expression to test its truth value.
    We use AND and IOR both for logical and bit-wise operations, so
    interpret them as logical unless they are inside a comparison expression.
-   The first bit of FLAGS will be non-zero in that case.
+   The first bit of FLAGS will be nonzero in that case.
 
    Set the second bit of FLAGS to make references to attribute values use
    a cached local variable instead of calling a function.  */
@@ -4753,7 +4753,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)));
@@ -4907,8 +4907,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)
@@ -4918,7 +4918,7 @@ walk_attr_value (exp)
   switch (code)
     {
     case SYMBOL_REF:
-      if (! RTX_UNCHANGING_P (exp))
+      if (! ATTR_IND_SIMPLIFIED_P (exp))
        /* Since this is an arbitrary expression, it can look at anything.
           However, constant expressions do not depend on any particular
           insn.  */
@@ -5025,7 +5025,7 @@ write_attr_get (attr)
       return;
     }
 
-  printf ("     rtx insn;\n");
+  printf ("     rtx insn ATTRIBUTE_UNUSED;\n");
   printf ("{\n");
 
   if (GET_CODE (common_av->value) == FFS)
@@ -5276,11 +5276,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;
@@ -5325,7 +5325,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)
     {
@@ -5493,7 +5493,7 @@ write_indent (indent)
 }
 \f
 /* Write a subroutine that is given an insn that requires a delay slot, a
-   delay slot ordinal, and a candidate insn.  It returns non-zero if the
+   delay slot ordinal, and a candidate insn.  It returns nonzero if the
    candidate can be placed in the specified delay slot of the insn.
 
    We can write as many as three subroutines.  `eligible_for_delay'
@@ -5528,7 +5528,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");
@@ -5657,7 +5657,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.  */
@@ -5692,6 +5692,8 @@ write_function_unit_info ()
       printf ("}, \n");
     }
 
+  if (num_units == 0)
+    printf ("{\"dummy\", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* a dummy element */");
   printf ("};\n\n");
 }
 
@@ -5791,25 +5793,6 @@ write_complex_function (unit, name, connection)
 \f
 /* This page contains miscellaneous utility routines.  */
 
-/* Given a string, return the number of comma-separated elements in it.
-   Return 0 for the null string.  */
-
-static int
-n_comma_elts (s)
-     const char *s;
-{
-  int n;
-
-  if (*s == '\0')
-    return 0;
-
-  for (n = 1; *s; s++)
-    if (*s == ',')
-      n++;
-
-  return n;
-}
-
 /* Given a pointer to a (char *), return a malloc'ed string containing the
    next comma-separated element.  Advance the pointer to after the string
    scanned, or the end-of-string.  Return NULL if at end of string.  */
@@ -5818,27 +5801,18 @@ static char *
 next_comma_elt (pstr)
      const char **pstr;
 {
-  char *out_str;
-  const char *p;
-
-  if (**pstr == '\0')
-    return NULL;
-
-  /* Find end of string to compute length.  */
-  for (p = *pstr; *p != ',' && *p != '\0'; p++)
-    ;
+  const char *start;
 
-  out_str = attr_string (*pstr, p - *pstr);
-  *pstr = p;
+  start = scan_comma_elt (pstr);
 
-  if (**pstr == ',')
-    (*pstr)++;
+  if (start == NULL)
+    return NULL;
 
-  return out_str;
+  return attr_string (start, *pstr - start);
 }
 
 /* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
-   is non-zero, build a new attribute, if one does not exist.  */
+   is nonzero, build a new attribute, if one does not exist.  */
 
 static struct attr_desc *
 find_attr (name, create)
@@ -5879,7 +5853,7 @@ find_attr (name, create)
 
 /* Create internal attribute with the given default value.  */
 
-static void
+void
 make_internal_attr (name, value, special)
      const char *name;
      rtx value;
@@ -5946,7 +5920,7 @@ find_single_value (attr)
 
 /* Return (attr_value "n") */
 
-static rtx
+rtx
 make_numeric_value (n)
      int n;
 {
@@ -5983,17 +5957,17 @@ 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))
+  if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
     return orig;
 
-  MEM_IN_STRUCT_P (orig) = 1;
+  ATTR_CURR_SIMPLIFIED_P (orig) = 1;
   return orig;
 
 #if 0
@@ -6012,7 +5986,7 @@ copy_rtx_unchanging (orig)
 
   copy = rtx_alloc (code);
   PUT_MODE (copy, GET_MODE (orig));
-  RTX_UNCHANGING_P (copy) = 1;
+  ATTR_IND_SIMPLIFIED_P (copy) = 1;
 
   memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
          GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
@@ -6073,9 +6047,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);
@@ -6086,8 +6060,8 @@ main (argc, argv)
   XWINT (true_rtx, 0) = 1;
   false_rtx = rtx_alloc (CONST_INT);
   XWINT (false_rtx, 0) = 0;
-  RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
-  RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
+  ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
+  ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
 
   alternative_name = attr_string ("alternative", strlen ("alternative"));
 
@@ -6096,6 +6070,7 @@ from the machine description file `md'.  */\n\n");
 
   /* Read the machine description.  */
 
+  initiate_automaton_gen (argc, argv);
   while (1)
     {
       int lineno;
@@ -6124,6 +6099,54 @@ from the machine description file `md'.  */\n\n");
          gen_unit (desc, lineno);
          break;
 
+       case DEFINE_CPU_UNIT:
+         gen_cpu_unit (desc);
+         break;
+         
+       case DEFINE_QUERY_CPU_UNIT:
+         gen_query_cpu_unit (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;
        }
@@ -6148,12 +6171,19 @@ from the machine description file `md'.  */\n\n");
   if (num_delays)
     expand_delays ();
 
-  /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
-  if (num_units)
-    expand_units ();
+  if (num_units || num_dfa_decls)
+    {
+      /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
+      expand_units ();
+      /* Build DFA, output some functions and expand DFA information
+        into new attributes.  */
+      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 \"tm_p.h\"\n");
   printf ("#include \"insn-config.h\"\n");
@@ -6164,6 +6194,7 @@ from the machine description file `md'.  */\n\n");
   printf ("#include \"insn-attr.h\"\n");
   printf ("#include \"toplev.h\"\n");
   printf ("#include \"flags.h\"\n");
+  printf ("#include \"function.h\"\n");
   printf ("\n");
   printf ("#define operands recog_data.operand\n\n");
 
@@ -6210,7 +6241,18 @@ from the machine description file `md'.  */\n\n");
     for (attr = attrs[i]; attr; attr = attr->next)
       {
        if (! attr->is_special && ! attr->is_const)
-         write_attr_get (attr);
+         {
+           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 out delay eligibility information, if DEFINE_DELAY present.
@@ -6225,9 +6267,14 @@ from the machine description file `md'.  */\n\n");
        write_eligible_delay ("annul_false");
     }
 
-  /* Write out information about function units.  */
-  if (num_units)
-    write_function_unit_info ();
+  if (num_units || num_dfa_decls)
+    {
+      /* Write out information about function units.  */
+      write_function_unit_info ();
+      /* Output code for pipeline hazards recognition based on DFA
+        (deterministic finite state automata.  */
+      write_automata ();
+    }
 
   /* Write out constant delay slot info */
   write_const_num_delay_slots ();