/* Generate code from machine description to compute values of attributes.
   Copyright (C) 1991-2021 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 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with 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.

   It produces a series of functions named `get_attr_...', one for each insn
   attribute.  Each of these is given the rtx for an insn and returns a member
   of the enum for the attribute.

   These subroutines have the form of a `switch' on the INSN_CODE (via
   `recog_memoized').  Each case either returns a constant attribute value
   or a value that depends on tests on other attributes, the form of
   operands, or some random C expression (encoded with a SYMBOL_REF
   expression).

   If the attribute `alternative', or a random C expression is present,
   `constrain_operands' is called.  If either of these cases of a reference to
   an operand is found, `extract_insn' is called.

   The special attribute `length' is also recognized.  For this operand,
   expressions involving the address of an operand or the current insn,
   (address (pc)), are valid.  In this case, an initial pass is made to
   set all lengths that do not depend on address.  Those that do are set to
   the maximum length.  Then each insn that depends on an address is checked
   and possibly has its length changed.  The process repeats until no further
   changed are made.  The resulting lengths are saved for use by
   `get_attr_length'.

   A special form of DEFINE_ATTR, where the expression for default value is a
   CONST expression, indicates an attribute that is constant for a given run
   of the compiler.  The subroutine generated for these attributes has no
   parameters as it does not depend on any particular insn.  Constant
   attributes are typically used to specify which variety of processor is
   used.

   Internal attributes are defined to handle DEFINE_DELAY and
   DEFINE_INSN_RESERVATION.  Special routines are output for these cases.

   This program works by keeping a list of possible values for each attribute.
   These include the basic attribute choices, default values for attribute, and
   all derived quantities.

   As the description file is read, the definition for each insn is saved in a
   `struct insn_def'.   When the file reading is complete, a `struct insn_ent'
   is created for each insn and chained to the corresponding attribute value,
   either that specified, or the default.

   An optimization phase is then run.  This simplifies expressions for each
   insn.  EQ_ATTR tests are resolved, whenever possible, to a test that
   indicates when the attribute has the specified value for the insn.  This
   avoids recursive calls during compilation.

   The strategy used when processing DEFINE_DELAY definitions is to create
   arbitrarily complex expressions and have the optimization simplify them.

   Once optimization is complete, any required routines and definitions
   will be written.

   An optimization that is not yet implemented is to hoist the constant
   expressions entirely out of the routines and definitions that are written.
   A way to do this is to iterate over all possible combinations of values
   for constant attributes and generate a set of functions for that given
   combination.  An initialization function would be written that evaluates
   the attributes and installs the corresponding set of routines and
   definitions (each would be accessed through a pointer).

   We use the flags in an RTX as follows:
   `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
      independent of the insn code.
   `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
      for the insn code currently being processed (see optimize_attrs).
   `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
      (see attr_rtx).  */

#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), return_val))

#if 0
#define strcmp_check(S1, S2) ((S1) == (S2)		\
			      ? 0			\
			      : (gcc_assert (strcmp ((S1), (S2))), 1))
#else
#define strcmp_check(S1, S2) ((S1) != (S2))
#endif

#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"
#include "fnmatch.h"

#define DEBUG 0

/* Flags for make_internal_attr's `special' parameter.  */
#define ATTR_NONE		0
#define ATTR_SPECIAL		(1 << 0)

static struct obstack obstack1, 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)

/* Define structures used to record attributes and values.  */

/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
   encountered, we store all the relevant information into a
   `struct insn_def'.  This is done to allow attribute definitions to occur
   anywhere in the file.  */

class insn_def
{
public:
  class insn_def *next;	/* Next insn in chain.  */
  rtx def;			/* The DEFINE_...  */
  int insn_code;		/* Instruction number.  */
  int insn_index;		/* Expression number in file, for errors.  */
  file_location loc;		/* Where in the .md files it occurs.  */
  int num_alternatives;		/* Number of alternatives.  */
  int vec_idx;			/* Index of attribute vector in `def'.  */
};

/* Once everything has been read in, we store in each attribute value a list
   of insn codes that have that value.  Here is the structure used for the
   list.  */

struct insn_ent
{
  struct insn_ent *next;	/* Next in chain.  */
  class insn_def *def;		/* Instruction definition.  */
};

/* Each value of an attribute (either constant or computed) is assigned a
   structure which is used as the listhead of the insns that have that
   value.  */

struct attr_value
{
  rtx value;			/* Value of attribute.  */
  struct attr_value *next;	/* Next attribute value in chain.  */
  struct insn_ent *first_insn;	/* First insn with this value.  */
  int num_insns;		/* Number of insns with this value.  */
  int has_asm_insn;		/* True if this value used for `asm' insns */
};

/* Structure for each attribute.  */

class attr_desc
{
public:
  char *name;			/* Name of attribute.  */
  const char *enum_name;	/* Enum name for DEFINE_ENUM_NAME.  */
  class attr_desc *next;	/* Next attribute.  */
  struct attr_value *first_value; /* First value of this attribute.  */
  struct attr_value *default_val; /* Default value for this attribute.  */
  file_location loc;		/* Where in the .md files it occurs.  */
  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'.  */
};

/* Structure for each DEFINE_DELAY.  */

class delay_desc
{
public:
  rtx def;			/* DEFINE_DELAY expression.  */
  class delay_desc *next;	/* Next DEFINE_DELAY.  */
  file_location loc;		/* Where in the .md files it occurs.  */
  int num;			/* Number of DEFINE_DELAY, starting at 1.  */
};

struct attr_value_list
{
  struct attr_value *av;
  struct insn_ent *ie;
  class attr_desc *attr;
  struct attr_value_list *next;
};

/* Listheads of above structures.  */

/* This one is indexed by the first character of the attribute name.  */
#define MAX_ATTRS_INDEX 256
static class attr_desc *attrs[MAX_ATTRS_INDEX];
static class insn_def *defs;
static class delay_desc *delays;
struct attr_value_list **insn_code_values;

/* Other variables.  */

static int insn_index_number;
static int got_define_asm_attributes;
static int must_extract;
static int must_constrain;
static int address_used;
static int length_used;
static int num_delays;
static int have_annul_true, have_annul_false;
static int num_insn_ents;

/* Stores, for each insn code, the number of constraint alternatives.  */

static int *insn_n_alternatives;

/* Stores, for each insn code, a bitmap that has bits on for each possible
   alternative.  */

/* Keep this in sync with recog.h.  */
typedef uint64_t alternative_mask;
static alternative_mask *insn_alternatives;

/* Used to simplify expressions.  */

static rtx true_rtx, false_rtx;

/* Used to reduce calls to `strcmp' */

static const char *alternative_name;
static const char *length_str;
static const char *delay_type_str;
static const char *delay_1_0_str;
static const char *num_delay_slots_str;

/* Simplify an expression.  Only call the routine if there is something to
   simplify.  */
#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)	\
  (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP)	\
   : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))

#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))

/* 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 class attr_desc *find_attr (const char **, int);
static rtx mk_attr_alt             (alternative_mask);
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);
static int min_attr_value	   (rtx);
static unsigned int attr_value_alignment (rtx);
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 void clear_struct_flag      (rtx);
static void write_attr_valueq	   (FILE *, class attr_desc *, const char *);
static struct attr_value *find_most_used  (class attr_desc *);
static void write_attr_set	   (FILE *, class attr_desc *, int, rtx,
				    const char *, const char *, rtx,
				    int, int, unsigned int);
static void write_attr_case	   (FILE *, class attr_desc *,
				    struct attr_value *,
				    int, const char *, const char *, int, rtx);
static void write_attr_value	   (FILE *, class attr_desc *, rtx);
static void write_upcase	   (FILE *, const char *);
static void write_indent	   (FILE *, 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))

/* This gen* file is unique, in that it writes out multiple files.

   Before GCC 4.8, insn-attrtab.c was written out containing many large
   functions and tables.  This made insn-attrtab.c _the_ bottle-neck in
   a parallel build, and even made it impossible to build GCC on machines
   with relatively small RAM space (PR other/29442).  Therefore, the
   atrribute functions/tables are now written out to three separate
   files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
   all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
   rest goes to ATTR_FILE_NAME.  */

static const char *attr_file_name = NULL;
static const char *dfa_file_name = NULL;
static const char *latency_file_name = NULL;

static FILE *attr_file, *dfa_file, *latency_file;

/* Hash table for sharing RTL and strings.  */

/* Each hash table slot is a bucket containing a chain of these structures.
   Strings are given negative hash codes; RTL expressions are given positive
   hash codes.  */

struct attr_hash
{
  struct attr_hash *next;	/* Next structure in the bucket.  */
  unsigned int hashcode;	/* Hash code of this rtx or string.  */
  union
    {
      char *str;		/* The string (negative hash codes) */
      rtx rtl;			/* or the RTL recorded here.  */
    } u;
};

/* Now here is the hash table.  When recording an RTL, it is added to
   the slot whose index is the hash code mod the table size.  Note
   that the hash table is used for several kinds of RTL (see attr_rtx)
   and for strings.  While all these live in the same table, they are
   completely independent, and the hash code is computed differently
   for each.  */

#define RTL_HASH_SIZE 4093
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) ((intptr_t) (RTL) & 0777777)

/* Add an entry to the hash table for RTL with hash code HASHCODE.  */

static void
attr_hash_add_rtx (unsigned int hashcode, rtx rtl)
{
  struct attr_hash *h;

  h = XOBNEW (hash_obstack, struct attr_hash);
  h->hashcode = hashcode;
  h->u.rtl = rtl;
  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
}

/* Add an entry to the hash table for STRING with hash code HASHCODE.  */

static void
attr_hash_add_string (unsigned int hashcode, char *str)
{
  struct attr_hash *h;

  h = XOBNEW (hash_obstack, struct attr_hash);
  h->hashcode = -hashcode;
  h->u.str = str;
  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
}

/* Generate an RTL expression, but avoid duplicates.
   Set the ATTR_PERMANENT_P flag for these permanent objects.

   In some cases we cannot uniquify; then we return an ordinary
   impermanent rtx with ATTR_PERMANENT_P clear.

   Args are as follows:

   rtx attr_rtx (code, [element1, ..., elementn])  */

static rtx
attr_rtx_1 (enum rtx_code code, va_list p)
{
  rtx rt_val = NULL_RTX;/* RTX to return to caller...		*/
  unsigned int hashcode;
  struct attr_hash *h;
  struct obstack *old_obstack = rtl_obstack;
  int permanent_p = 1;

  /* 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.  */

  if (GET_RTX_CLASS (code) == RTX_UNARY)
    {
      rtx arg0 = va_arg (p, rtx);

      if (! ATTR_PERMANENT_P (arg0))
	permanent_p = 0;

      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
	if (h->hashcode == hashcode
	    && GET_CODE (h->u.rtl) == code
	    && XEXP (h->u.rtl, 0) == arg0)
	  return h->u.rtl;

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XEXP (rt_val, 0) = arg0;
	}
    }
  else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
  	   || GET_RTX_CLASS (code) == RTX_COMM_ARITH
  	   || GET_RTX_CLASS (code) == RTX_COMPARE
  	   || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
    {
      rtx arg0 = va_arg (p, rtx);
      rtx arg1 = va_arg (p, rtx);

      if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
	permanent_p = 0;

      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
	if (h->hashcode == hashcode
	    && GET_CODE (h->u.rtl) == code
	    && XEXP (h->u.rtl, 0) == arg0
	    && XEXP (h->u.rtl, 1) == arg1)
	  {
	    ATTR_CURR_SIMPLIFIED_P (h->u.rtl) = 0;
	    return h->u.rtl;
	  }

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XEXP (rt_val, 0) = arg0;
	  XEXP (rt_val, 1) = arg1;
	}
    }
  else if (code == SYMBOL_REF
	   || (GET_RTX_LENGTH (code) == 1
	       && GET_RTX_FORMAT (code)[0] == 's'))
    {
      char *arg0 = va_arg (p, char *);

      arg0 = DEF_ATTR_STRING (arg0);

      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
	if (h->hashcode == hashcode
	    && GET_CODE (h->u.rtl) == code
	    && XSTR (h->u.rtl, 0) == arg0)
	  return h->u.rtl;

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XSTR (rt_val, 0) = arg0;
	  if (code == SYMBOL_REF)
	    X0EXP (rt_val, 1) = NULL_RTX;
	}
    }
  else if (GET_RTX_LENGTH (code) == 2
	   && GET_RTX_FORMAT (code)[0] == 's'
	   && GET_RTX_FORMAT (code)[1] == 's')
    {
      char *arg0 = va_arg (p, char *);
      char *arg1 = va_arg (p, char *);

      arg0 = DEF_ATTR_STRING (arg0);
      arg1 = DEF_ATTR_STRING (arg1);

      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
	if (h->hashcode == hashcode
	    && GET_CODE (h->u.rtl) == code
	    && XSTR (h->u.rtl, 0) == arg0
	    && XSTR (h->u.rtl, 1) == arg1)
	  return h->u.rtl;

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XSTR (rt_val, 0) = arg0;
	  XSTR (rt_val, 1) = arg1;
	}
    }
  else if (GET_RTX_LENGTH (code) == 2
	   && GET_RTX_FORMAT (code)[0] == 'w'
	   && GET_RTX_FORMAT (code)[1] == 'w')
    {
      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
      HOST_WIDE_INT arg1 = va_arg (p, HOST_WIDE_INT);

      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
	if (h->hashcode == hashcode
	    && GET_CODE (h->u.rtl) == code
	    && XWINT (h->u.rtl, 0) == arg0
	    && XWINT (h->u.rtl, 1) == arg1)
	  return h->u.rtl;

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XWINT (rt_val, 0) = arg0;
	  XWINT (rt_val, 1) = arg1;
	}
    }
  else if (code == CONST_INT)
    {
      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
      if (arg0 == 0)
	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.  */

      fmt = GET_RTX_FORMAT (code);	/* Find the right format...  */
      for (i = 0; i < GET_RTX_LENGTH (code); i++)
	{
	  switch (*fmt++)
	    {
	    case '0':		/* Unused field.  */
	      break;

	    case 'i':		/* An integer?  */
	      XINT (rt_val, i) = va_arg (p, int);
	      break;

	    case 'w':		/* A wide integer? */
	      XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
	      break;

	    case 's':		/* A string?  */
	      XSTR (rt_val, i) = va_arg (p, char *);
	      break;

	    case 'e':		/* An expression?  */
	    case 'u':		/* An insn?  Same except when printing.  */
	      XEXP (rt_val, i) = va_arg (p, rtx);
	      break;

	    case 'E':		/* An RTX vector?  */
	      XVEC (rt_val, i) = va_arg (p, rtvec);
	      break;

	    default:
	      /* Don't need to handle 'p' for attributes.  */
	      gcc_unreachable ();
	    }
	}
      return rt_val;
    }

  rtl_obstack = old_obstack;
  attr_hash_add_rtx (hashcode, rt_val);
  ATTR_PERMANENT_P (rt_val) = permanent_p;
  return rt_val;
}

static rtx
attr_rtx (enum rtx_code code, ...)
{
  rtx result;
  va_list p;

  va_start (p, code);
  result = attr_rtx_1 (code, p);
  va_end (p);
  return result;
}

/* Create a new string printed with the printf line arguments into a space
   of at most LEN bytes:

   rtx attr_printf (len, format, [arg1, ..., argn])  */

static char *
attr_printf (unsigned int len, const char *fmt, ...)
{
  char str[256];
  va_list p;

  va_start (p, fmt);

  gcc_assert (len < sizeof str); /* Leave room for \0.  */

  vsprintf (str, fmt, p);
  va_end (p);

  return DEF_ATTR_STRING (str);
}

static rtx
attr_eq (const char *name, const char *value)
{
  return attr_rtx (EQ_ATTR, name, value);
}

static const char *
attr_numeral (int n)
{
  return XSTR (make_numeric_value (n), 0);
}

/* Return a permanent (possibly shared) copy of a string STR (not assumed
   to be null terminated) with LEN bytes.  */

static char *
attr_string (const char *str, int len)
{
  struct attr_hash *h;
  unsigned int hashcode;
  int i;
  char *new_str;

  /* Compute the hash code.  */
  hashcode = (len + 1) * 613U + (unsigned) str[0];
  for (i = 1; i < len; i += 2)
    hashcode = ((hashcode * 613) + (unsigned) str[i]);
  if ((int) hashcode < 0)
    hashcode = -hashcode;

  /* Search the table for the string.  */
  for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
    if (h->hashcode == -hashcode && h->u.str[0] == str[0]
	&& !strncmp (h->u.str, str, len))
      return h->u.str;			/* <-- return if found.  */

  /* Not found; create a permanent copy and add it to the hash table.  */
  new_str = XOBNEWVAR (hash_obstack, char, len + 1);
  memcpy (new_str, str, len);
  new_str[len] = '\0';
  attr_hash_add_string (hashcode, new_str);
  rtx_reader_ptr->copy_md_ptr_loc (new_str, str);

  return new_str;			/* Return the new string.  */
}

/* Check two rtx's for equality of contents,
   taking advantage of the fact that if both are hashed
   then they can't be equal unless they are the same object.  */

static int
attr_equal_p (rtx x, rtx y)
{
  return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
		     && rtx_equal_p (x, y)));
}

/* Given a test expression EXP for attribute ATTR, ensure it is validly
   formed.  LOC is the location of the .md construct that contains EXP.

   Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
   and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
   test first so that (eq_attr "att" "!a1,a2,a3") works as expected.

   Update the string address in EQ_ATTR expression to be the same used
   in the attribute (or `alternative_name') to speed up subsequent
   `find_attr' calls and eliminate most `strcmp' calls.

   Return the new expression, if any.  */

static rtx
check_attr_test (file_location loc, rtx exp, attr_desc *attr)
{
  struct attr_value *av;
  const char *name_ptr, *p;
  rtx orexp, newexp;

  switch (GET_CODE (exp))
    {
    case EQ_ATTR:
      /* Handle negation test.  */
      if (XSTR (exp, 1)[0] == '!')
	return check_attr_test (loc,
				attr_rtx (NOT,
					  attr_eq (XSTR (exp, 0),
						   &XSTR (exp, 1)[1])),
				attr);

      else if (n_comma_elts (XSTR (exp, 1)) == 1)
	{
	  attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
	  if (attr2 == NULL)
	    {
	      if (! strcmp (XSTR (exp, 0), "alternative"))
		return mk_attr_alt (((alternative_mask) 1)
				    << atoi (XSTR (exp, 1)));
	      else
		fatal_at (loc, "unknown attribute `%s' in definition of"
			  " attribute `%s'", XSTR (exp, 0), attr->name);
	    }

	  if (attr->is_const && ! attr2->is_const)
	    fatal_at (loc, "constant attribute `%s' cannot test non-constant"
		      " attribute `%s'", attr->name, attr2->name);

	  /* Copy this just to make it permanent,
	     so expressions using it can be permanent too.  */
	  exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));

	  /* It shouldn't be possible to simplify the value given to a
	     constant attribute, so don't expand this until it's time to
	     write the test expression.  */
	  if (attr2->is_const)
	    ATTR_IND_SIMPLIFIED_P (exp) = 1;

	  if (attr2->is_numeric)
	    {
	      for (p = XSTR (exp, 1); *p; p++)
		if (! ISDIGIT (*p))
		  fatal_at (loc, "attribute `%s' takes only numeric values",
			    attr2->name);
	    }
	  else
	    {
	      for (av = attr2->first_value; av; av = av->next)
		if (GET_CODE (av->value) == CONST_STRING
		    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
		  break;

	      if (av == NULL)
		fatal_at (loc, "unknown value `%s' for attribute `%s'",
			  XSTR (exp, 1), attr2->name);
	    }
	}
      else
	{
	  if (! strcmp (XSTR (exp, 0), "alternative"))
	    {
	      int set = 0;

	      name_ptr = XSTR (exp, 1);
	      while ((p = next_comma_elt (&name_ptr)) != NULL)
		set |= ((alternative_mask) 1) << atoi (p);

	      return mk_attr_alt (set);
	    }
	  else
	    {
	      /* Make an IOR tree of the possible values.  */
	      orexp = false_rtx;
	      name_ptr = XSTR (exp, 1);
	      while ((p = next_comma_elt (&name_ptr)) != NULL)
		{
		  newexp = attr_eq (XSTR (exp, 0), p);
		  orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
		}

	      return check_attr_test (loc, orexp, attr);
	    }
	}
      break;

    case ATTR_FLAG:
      break;

    case CONST_INT:
      /* Either TRUE or FALSE.  */
      if (XWINT (exp, 0))
	return true_rtx;
      else
	return false_rtx;

    case IOR:
    case AND:
      XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
      XEXP (exp, 1) = check_attr_test (loc, XEXP (exp, 1), attr);
      break;

    case NOT:
      XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
      break;

    case MATCH_TEST:
      exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
      break;

    case MATCH_OPERAND:
      if (attr->is_const)
	fatal_at (loc, "invalid operator `%s' in definition of constant"
		  " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
		  attr->name);
      /* These cases can't be simplified.  */
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
      break;

    case LE:  case LT:  case GT:  case GE:
    case LEU: case LTU: case GTU: case GEU:
    case NE:  case EQ:
      if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
	  && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
	exp = attr_rtx (GET_CODE (exp),
			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
      /* These cases can't be simplified.  */
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
      break;

    case SYMBOL_REF:
      if (attr->is_const)
	{
	  /* These cases are valid for constant attributes, but can't be
	     simplified.  */
	  exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
	  ATTR_IND_SIMPLIFIED_P (exp) = 1;
	  break;
	}
      /* FALLTHRU */
    default:
      fatal_at (loc, "invalid operator `%s' in definition of attribute"
		" `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
    }

  return exp;
}

/* Given an expression EXP, ensure that it is validly formed and that
   all named attribute values are valid for ATTR.  Issue an error if not.
   LOC is the location of the .md construct that contains EXP.

   Return a perhaps modified replacement expression for the value.  */

static rtx
check_attr_value (file_location loc, rtx exp, class attr_desc *attr)
{
  struct attr_value *av;
  const char *p;
  int i;

  switch (GET_CODE (exp))
    {
    case CONST_INT:
      if (!attr->is_numeric)
	{
	  error_at (loc,
		    "CONST_INT not valid for non-numeric attribute `%s'",
		    attr->name);
	  break;
	}

      if (INTVAL (exp) < 0)
	{
	  error_at (loc,
		    "negative numeric value specified for attribute `%s'",
		    attr->name);
	  break;
	}
      break;

    case CONST_STRING:
      if (! strcmp (XSTR (exp, 0), "*"))
	break;

      if (attr->is_numeric)
	{
	  p = XSTR (exp, 0);
	  for (; *p; p++)
	    if (! ISDIGIT (*p))
	      {
		error_at (loc,
			  "non-numeric value specified for numeric"
			  " attribute `%s'", attr->name);
		break;
	      }
	  break;
	}

      for (av = attr->first_value; av; av = av->next)
	if (GET_CODE (av->value) == CONST_STRING
	    && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
	  break;

      if (av == NULL)
	error_at (loc, "unknown value `%s' for attribute `%s'",
		  XSTR (exp, 0), attr->name);
      break;

    case IF_THEN_ELSE:
      XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
      XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
      XEXP (exp, 2) = check_attr_value (loc, XEXP (exp, 2), attr);
      break;

    case PLUS:
    case MINUS:
    case MULT:
    case DIV:
    case MOD:
      if (!attr->is_numeric)
	{
	  error_at (loc, "invalid operation `%s' for non-numeric"
		    " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
		    attr->name);
	  break;
	}
      /* Fall through.  */

    case IOR:
    case AND:
      XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
      XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
      break;

    case FFS:
    case CLZ:
    case CTZ:
    case POPCOUNT:
    case PARITY:
    case BSWAP:
      XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
      break;

    case COND:
      if (XVECLEN (exp, 0) % 2 != 0)
	{
	  error_at (loc, "first operand of COND must have even length");
	  break;
	}

      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	{
	  XVECEXP (exp, 0, i) = check_attr_test (attr->loc,
						 XVECEXP (exp, 0, i),
						 attr);
	  XVECEXP (exp, 0, i + 1)
	    = check_attr_value (loc, XVECEXP (exp, 0, i + 1), attr);
	}

      XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
      break;

    case ATTR:
      {
	class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
	if (attr2 == NULL)
	  error_at (loc, "unknown attribute `%s' in ATTR",
		    XSTR (exp, 0));
	else if (attr->is_const && ! attr2->is_const)
	  error_at (attr->loc,
		    "constant attribute `%s' cannot refer to non-constant"
		    " attribute `%s'", attr->name, attr2->name);
	else if (attr->is_numeric != attr2->is_numeric)
	  error_at (loc,
		    "numeric attribute mismatch calling `%s' from `%s'",
		    attr2->name, attr->name);
      }
      break;

    case SYMBOL_REF:
      /* A constant SYMBOL_REF is valid as a constant attribute test and
         is expanded later by make_canonical into a COND.  In a non-constant
         attribute test, it is left be.  */
      return attr_rtx (SYMBOL_REF, XSTR (exp, 0));

    default:
      error_at (loc, "invalid operator `%s' in definition of attribute `%s'",
		GET_RTX_NAME (GET_CODE (exp)), attr->name);
      break;
    }

  return exp;
}

/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
   It becomes a COND with each test being (eq_attr "alternative" "n") */

static rtx
convert_set_attr_alternative (rtx exp, class insn_def *id)
{
  int num_alt = id->num_alternatives;
  rtx condexp;
  int i;

  if (XVECLEN (exp, 1) != num_alt)
    {
      error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
		" was %d expected %d", XVECLEN (exp, 1), num_alt);
      return NULL_RTX;
    }

  /* Make a COND with all tests but the last.  Select the last value via the
     default.  */
  condexp = rtx_alloc (COND);
  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);

  for (i = 0; i < num_alt - 1; i++)
    {
      const char *p;
      p = attr_numeral (i);

      XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
      XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
    }

  XEXP (condexp, 1) = XVECEXP (exp, 1, i);

  return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
}

/* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
   list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */

static rtx
convert_set_attr (rtx exp, class insn_def *id)
{
  rtx newexp;
  const char *name_ptr;
  char *p;
  int n;

  /* See how many alternative specified.  */
  n = n_comma_elts (XSTR (exp, 1));
  if (n == 1)
    return attr_rtx (SET,
		     attr_rtx (ATTR, XSTR (exp, 0)),
		     attr_rtx (CONST_STRING, XSTR (exp, 1)));

  newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
  XSTR (newexp, 0) = XSTR (exp, 0);
  XVEC (newexp, 1) = rtvec_alloc (n);

  /* Process each comma-separated name.  */
  name_ptr = XSTR (exp, 1);
  n = 0;
  while ((p = next_comma_elt (&name_ptr)) != NULL)
    XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);

  return convert_set_attr_alternative (newexp, id);
}

/* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
   and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
   expressions.  */

static void
check_defs (void)
{
  class insn_def *id;
  class attr_desc *attr;
  int i;
  rtx value;

  for (id = defs; id; id = id->next)
    {
      if (XVEC (id->def, id->vec_idx) == NULL)
	continue;

      for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
	{
	  value = XVECEXP (id->def, id->vec_idx, i);
	  switch (GET_CODE (value))
	    {
	    case SET:
	      if (GET_CODE (XEXP (value, 0)) != ATTR)
		{
		  error_at (id->loc, "bad attribute set");
		  value = NULL_RTX;
		}
	      break;

	    case SET_ATTR_ALTERNATIVE:
	      value = convert_set_attr_alternative (value, id);
	      break;

	    case SET_ATTR:
	      value = convert_set_attr (value, id);
	      break;

	    default:
	      error_at (id->loc, "invalid attribute code %s",
			GET_RTX_NAME (GET_CODE (value)));
	      value = NULL_RTX;
	    }
	  if (value == NULL_RTX)
	    continue;

	  if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
	    {
	      error_at (id->loc, "unknown attribute %s",
			XSTR (XEXP (value, 0), 0));
	      continue;
	    }

	  XVECEXP (id->def, id->vec_idx, i) = value;
	  XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
	}
    }
}

/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
   expressions by converting them into a COND.  This removes cases from this
   program.  Also, replace an attribute value of "*" with the default attribute
   value.  LOC is the location to use for error reporting.  */

static rtx
make_canonical (file_location loc, class attr_desc *attr, rtx exp)
{
  int i;
  rtx newexp;

  switch (GET_CODE (exp))
    {
    case CONST_INT:
      exp = make_numeric_value (INTVAL (exp));
      break;

    case CONST_STRING:
      if (! strcmp (XSTR (exp, 0), "*"))
	{
	  if (attr->default_val == 0)
	    fatal_at (loc, "(attr_value \"*\") used in invalid context");
	  exp = attr->default_val->value;
	}
      else
	XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));

      break;

    case SYMBOL_REF:
      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.  */
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
      exp = check_attr_value (loc, exp, attr);
      break;

    case IF_THEN_ELSE:
      newexp = rtx_alloc (COND);
      XVEC (newexp, 0) = rtvec_alloc (2);
      XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
      XVECEXP (newexp, 0, 1) = XEXP (exp, 1);

      XEXP (newexp, 1) = XEXP (exp, 2);

      exp = newexp;
      /* Fall through to COND case since this is now a COND.  */
      gcc_fallthrough ();

    case COND:
      {
	int allsame = 1;
	rtx defval;

	/* First, check for degenerate COND.  */
	if (XVECLEN (exp, 0) == 0)
	  return make_canonical (loc, attr, XEXP (exp, 1));
	defval = XEXP (exp, 1) = make_canonical (loc, attr, XEXP (exp, 1));

	for (i = 0; i < XVECLEN (exp, 0); i += 2)
	  {
	    XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
	    XVECEXP (exp, 0, i + 1)
	      = make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
	    if (! attr_equal_p (XVECEXP (exp, 0, i + 1), defval))
	      allsame = 0;
	  }
	if (allsame)
	  return defval;
      }
      break;

    default:
      break;
    }

  return exp;
}

static rtx
copy_boolean (rtx exp)
{
  if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
    return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
		     copy_boolean (XEXP (exp, 1)));
  else if (GET_CODE (exp) == NOT)
    return attr_rtx (NOT, copy_boolean (XEXP (exp, 0)));
  if (GET_CODE (exp) == MATCH_OPERAND)
    {
      XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
      XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
    }
  else if (GET_CODE (exp) == EQ_ATTR)
    {
      XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
      XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
    }

  return exp;
}

/* Given a value and an attribute description, return a `struct attr_value *'
   that represents that value.  This is either an existing structure, if the
   value has been previously encountered, or a newly-created structure.

   `insn_code' is the code of an insn whose attribute has the specified
   value (-2 if not processing an insn).  We ensure that all insns for
   a given value have the same number of alternatives if the value checks
   alternatives.  LOC is the location to use for error reporting.  */

static struct attr_value *
get_attr_value (file_location loc, rtx value, class attr_desc *attr,
		int insn_code)
{
  struct attr_value *av;
  alternative_mask num_alt = 0;

  value = make_canonical (loc, attr, value);
  if (compares_alternatives_p (value))
    {
      if (insn_code < 0 || insn_alternatives == NULL)
	fatal_at (loc, "(eq_attr \"alternatives\" ...) used in non-insn"
		  " context");
      else
	num_alt = insn_alternatives[insn_code];
    }

  for (av = attr->first_value; av; av = av->next)
    if (attr_equal_p (value, av->value)
	&& (num_alt == 0 || av->first_insn == NULL
	    || insn_alternatives[av->first_insn->def->insn_code]))
      return av;

  av = oballoc (struct attr_value);
  av->value = value;
  av->next = attr->first_value;
  attr->first_value = av;
  av->first_insn = NULL;
  av->num_insns = 0;
  av->has_asm_insn = 0;

  return av;
}

/* After all DEFINE_DELAYs have been read in, create internal attributes
   to generate the required routines.

   First, we compute the number of delay slots for each insn (as a COND of
   each of the test expressions in DEFINE_DELAYs).  Then, if more than one
   delay type is specified, we compute a similar function giving the
   DEFINE_DELAY ordinal for each insn.

   Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
   tells whether a given insn can be in that delay slot.

   Normal attribute filling and optimization expands these to contain the
   information needed to handle delay slots.  */

static void
expand_delays (void)
{
  class delay_desc *delay;
  rtx condexp;
  rtx newexp;
  int i;
  char *p;

  /* First, generate data for `num_delay_slots' function.  */

  condexp = rtx_alloc (COND);
  XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
  XEXP (condexp, 1) = make_numeric_value (0);

  for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
    {
      XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
      XVECEXP (condexp, 0, i + 1)
	= make_numeric_value (XVECLEN (delay->def, 1) / 3);
    }

  make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);

  /* If more than one delay type, do the same for computing the delay type.  */
  if (num_delays > 1)
    {
      condexp = rtx_alloc (COND);
      XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
      XEXP (condexp, 1) = make_numeric_value (0);

      for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
	{
	  XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
	  XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
	}

      make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
    }

  /* For each delay possibility and delay slot, compute an eligibility
     attribute for non-annulled insns and for each type of annulled (annul
     if true and annul if false).  */
  for (delay = delays; delay; delay = delay->next)
    {
      for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
	{
	  condexp = XVECEXP (delay->def, 1, i);
	  if (condexp == 0)
	    condexp = false_rtx;
	  newexp = attr_rtx (IF_THEN_ELSE, condexp,
			     make_numeric_value (1), make_numeric_value (0));

	  p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
			   "*delay_%d_%d", delay->num, i / 3);
	  make_internal_attr (p, newexp, ATTR_SPECIAL);

	  if (have_annul_true)
	    {
	      condexp = XVECEXP (delay->def, 1, i + 1);
	      if (condexp == 0) condexp = false_rtx;
	      newexp = attr_rtx (IF_THEN_ELSE, condexp,
				 make_numeric_value (1),
				 make_numeric_value (0));
	      p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
			       "*annul_true_%d_%d", delay->num, i / 3);
	      make_internal_attr (p, newexp, ATTR_SPECIAL);
	    }

	  if (have_annul_false)
	    {
	      condexp = XVECEXP (delay->def, 1, i + 2);
	      if (condexp == 0) condexp = false_rtx;
	      newexp = attr_rtx (IF_THEN_ELSE, condexp,
				 make_numeric_value (1),
				 make_numeric_value (0));
	      p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
			       "*annul_false_%d_%d", delay->num, i / 3);
	      make_internal_attr (p, newexp, ATTR_SPECIAL);
	    }
	}
    }
}

/* Once all attributes and insns have been read and checked, we construct for
   each attribute value a list of all the insns that have that value for
   the attribute.  */

static void
fill_attr (class attr_desc *attr)
{
  struct attr_value *av;
  struct insn_ent *ie;
  class insn_def *id;
  int i;
  rtx value;

  /* Don't fill constant attributes.  The value is independent of
     any particular insn.  */
  if (attr->is_const)
    return;

  for (id = defs; id; id = id->next)
    {
      /* If no value is specified for this insn for this attribute, use the
	 default.  */
      value = NULL;
      if (XVEC (id->def, id->vec_idx))
	for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
	  if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
			      attr->name))
	    value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);

      if (value == NULL)
	av = attr->default_val;
      else
	av = get_attr_value (id->loc, value, attr, id->insn_code);

      ie = oballoc (struct insn_ent);
      ie->def = id;
      insert_insn_ent (av, ie);
    }
}

/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
   test that checks relative positions of insns (uses MATCH_DUP or PC).
   If so, replace it with what is obtained by passing the expression to
   ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
   recursively on each value (including the default value).  Otherwise,
   return the value returned by NO_ADDRESS_FN applied to EXP.  */

static rtx
substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
		    rtx (*address_fn) (rtx))
{
  int i;
  rtx newexp;

  if (GET_CODE (exp) == COND)
    {
      /* See if any tests use addresses.  */
      address_used = 0;
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	walk_attr_value (XVECEXP (exp, 0, i));

      if (address_used)
	return (*address_fn) (exp);

      /* Make a new copy of this COND, replacing each element.  */
      newexp = rtx_alloc (COND);
      XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	{
	  XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
	  XVECEXP (newexp, 0, i + 1)
	    = substitute_address (XVECEXP (exp, 0, i + 1),
				  no_address_fn, address_fn);
	}

      XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
					     no_address_fn, address_fn);

      return newexp;
    }

  else if (GET_CODE (exp) == IF_THEN_ELSE)
    {
      address_used = 0;
      walk_attr_value (XEXP (exp, 0));
      if (address_used)
	return (*address_fn) (exp);

      return attr_rtx (IF_THEN_ELSE,
		       substitute_address (XEXP (exp, 0),
					   no_address_fn, address_fn),
		       substitute_address (XEXP (exp, 1),
					   no_address_fn, address_fn),
		       substitute_address (XEXP (exp, 2),
					   no_address_fn, address_fn));
    }

  return (*no_address_fn) (exp);
}

/* Make new attributes from the `length' attribute.  The following are made,
   each corresponding to a function called from `shorten_branches' or
   `get_attr_length':

   *insn_default_length		This is the length of the insn to be returned
				by `get_attr_length' before `shorten_branches'
				has been called.  In each case where the length
				depends on relative addresses, the largest
				possible is used.  This routine is also used
				to compute the initial size of the insn.

   *insn_variable_length_p	This returns 1 if the insn's length depends
				on relative addresses, zero otherwise.

   *insn_current_length		This is only called when it is known that the
				insn has a variable length and returns the
				current length, based on relative addresses.
  */

static void
make_length_attrs (void)
{
  static const char *new_names[] =
    {
      "*insn_default_length",
      "*insn_min_length",
      "*insn_variable_length_p",
      "*insn_current_length"
    };
  static rtx (*const no_address_fn[]) (rtx)
    = {identity_fn,identity_fn, zero_fn, zero_fn};
  static rtx (*const address_fn[]) (rtx)
    = {max_fn, min_fn, one_fn, identity_fn};
  size_t i;
  class attr_desc *length_attr, *new_attr;
  struct attr_value *av, *new_av;
  struct insn_ent *ie, *new_ie;

  /* See if length attribute is defined.  If so, it must be numeric.  Make
     it special so we don't output anything for it.  */
  length_attr = find_attr (&length_str, 0);
  if (length_attr == 0)
    return;

  if (! length_attr->is_numeric)
    fatal_at (length_attr->loc, "length attribute must be numeric");

  length_attr->is_const = 0;
  length_attr->is_special = 1;

  /* Make each new attribute, in turn.  */
  for (i = 0; i < ARRAY_SIZE (new_names); i++)
    {
      make_internal_attr (new_names[i],
			  substitute_address (length_attr->default_val->value,
					      no_address_fn[i], address_fn[i]),
			  ATTR_NONE);
      new_attr = find_attr (&new_names[i], 0);
      for (av = length_attr->first_value; av; av = av->next)
	for (ie = av->first_insn; ie; ie = ie->next)
	  {
	    new_av = get_attr_value (ie->def->loc,
				     substitute_address (av->value,
							 no_address_fn[i],
							 address_fn[i]),
				     new_attr, ie->def->insn_code);
	    new_ie = oballoc (struct insn_ent);
	    new_ie->def = ie->def;
	    insert_insn_ent (new_av, new_ie);
	  }
    }
}

/* Utility functions called from above routine.  */

static rtx
identity_fn (rtx exp)
{
  return exp;
}

static rtx
zero_fn (rtx exp ATTRIBUTE_UNUSED)
{
  return make_numeric_value (0);
}

static rtx
one_fn (rtx exp ATTRIBUTE_UNUSED)
{
  return make_numeric_value (1);
}

static rtx
max_fn (rtx exp)
{
  return make_numeric_value (max_attr_value (exp));
}

static rtx
min_fn (rtx exp)
{
  return make_numeric_value (min_attr_value (exp));
}

static void
write_length_unit_log (FILE *outf)
{
  class attr_desc *length_attr = find_attr (&length_str, 0);
  struct attr_value *av;
  struct insn_ent *ie;
  unsigned int length_unit_log, length_or;

  if (length_attr)
    {
      length_or = attr_value_alignment (length_attr->default_val->value);
      for (av = length_attr->first_value; av; av = av->next)
	for (ie = av->first_insn; ie; ie = ie->next)
	  length_or |= attr_value_alignment (av->value);

      length_or = ~length_or;
      for (length_unit_log = 0; length_or & 1; length_or >>= 1)
	length_unit_log++;
    }
  else
    length_unit_log = 0;

  fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
}

/* Compute approximate cost of the expression.  Used to decide whether
   expression is cheap enough for inline.  */
static int
attr_rtx_cost (rtx x)
{
  int cost = 1;
  enum rtx_code code;
  if (!x)
    return 0;
  code = GET_CODE (x);
  switch (code)
    {
    case MATCH_OPERAND:
      if (XSTR (x, 1)[0])
	return 10;
      else
	return 1;

    case EQ_ATTR_ALT:
      return 1;

    case EQ_ATTR:
      /* Alternatives don't result into function call.  */
      if (!strcmp_check (XSTR (x, 0), alternative_name))
	return 1;
      else
	return 5;
    default:
      {
	int i, j;
	const char *fmt = GET_RTX_FORMAT (code);
	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
	  {
	    switch (fmt[i])
	      {
	      case 'V':
	      case 'E':
		for (j = 0; j < XVECLEN (x, i); j++)
		  cost += attr_rtx_cost (XVECEXP (x, i, j));
		break;
	      case 'e':
		cost += attr_rtx_cost (XEXP (x, i));
		break;
	      }
	  }
      }
      break;
    }
  return cost;
}

/* Take a COND expression and see if any of the conditions in it can be
   simplified.  If any are known true or known false for the particular insn
   code, the COND can be further simplified.

   Also call ourselves on any COND operations that are values of this COND.

   We do not modify EXP; rather, we make and return a new rtx.  */

static rtx
simplify_cond (rtx exp, int insn_code, int insn_index)
{
  int i, j;
  /* We store the desired contents here,
     then build a new expression if they don't match EXP.  */
  rtx defval = XEXP (exp, 1);
  rtx new_defval = XEXP (exp, 1);
  int len = XVECLEN (exp, 0);
  rtx *tests = XNEWVEC (rtx, len);
  int allsame = 1;
  rtx ret;

  /* This lets us free all storage allocated below, if appropriate.  */
  obstack_finish (rtl_obstack);

  memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));

  /* See if default value needs simplification.  */
  if (GET_CODE (defval) == COND)
    new_defval = simplify_cond (defval, insn_code, insn_index);

  /* Simplify the subexpressions, and see what tests we can get rid of.  */

  for (i = 0; i < len; i += 2)
    {
      rtx newtest, newval;

      /* Simplify this test.  */
      newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
      tests[i] = newtest;

      newval = tests[i + 1];
      /* See if this value may need simplification.  */
      if (GET_CODE (newval) == COND)
	newval = simplify_cond (newval, insn_code, insn_index);

      /* Look for ways to delete or combine this test.  */
      if (newtest == true_rtx)
	{
	  /* If test is true, make this value the default
	     and discard this + any following tests.  */
	  len = i;
	  defval = tests[i + 1];
	  new_defval = newval;
	}

      else if (newtest == false_rtx)
	{
	  /* If test is false, discard it and its value.  */
	  for (j = i; j < len - 2; j++)
	    tests[j] = tests[j + 2];
	  i -= 2;
	  len -= 2;
	}

      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]
	    = 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] = tests[j + 2];
	  len -= 2;
	  i -= 2;
	}

      else
	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], new_defval))
    len -= 2;

  /* See if we changed anything.  */
  if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
    allsame = 0;
  else
    for (i = 0; i < len; i++)
      if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
	{
	  allsame = 0;
	  break;
	}

  if (len == 0)
    {
      if (GET_CODE (defval) == COND)
	ret = simplify_cond (defval, insn_code, insn_index);
      else
	ret = defval;
    }
  else if (allsame)
    ret = exp;
  else
    {
      rtx newexp = rtx_alloc (COND);

      XVEC (newexp, 0) = rtvec_alloc (len);
      memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
      XEXP (newexp, 1) = new_defval;
      ret = newexp;
    }
  free (tests);
  return ret;
}

/* Remove an insn entry from an attribute value.  */

static void
remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
{
  struct insn_ent *previe;

  if (av->first_insn == ie)
    av->first_insn = ie->next;
  else
    {
      for (previe = av->first_insn; previe->next != ie; previe = previe->next)
	;
      previe->next = ie->next;
    }

  av->num_insns--;
  if (ie->def->insn_code == -1)
    av->has_asm_insn = 0;

  num_insn_ents--;
}

/* Insert an insn entry in an attribute value list.  */

static void
insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
{
  ie->next = av->first_insn;
  av->first_insn = ie;
  av->num_insns++;
  if (ie->def->insn_code == -1)
    av->has_asm_insn = 1;

  num_insn_ents++;
}

/* This is a utility routine to take an expression that is a tree of either
   AND or IOR expressions and insert a new term.  The new term will be
   inserted at the right side of the first node whose code does not match
   the root.  A new node will be created with the root's code.  Its left
   side will be the old right side and its right side will be the new
   term.

   If the `term' is itself a tree, all its leaves will be inserted.  */

static rtx
insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
{
  rtx newexp;

  /* Avoid consing in some special cases.  */
  if (code == AND && term == true_rtx)
    return exp;
  if (code == AND && term == false_rtx)
    return false_rtx;
  if (code == AND && exp == true_rtx)
    return term;
  if (code == AND && exp == false_rtx)
    return false_rtx;
  if (code == IOR && term == true_rtx)
    return true_rtx;
  if (code == IOR && term == false_rtx)
    return exp;
  if (code == IOR && exp == true_rtx)
    return true_rtx;
  if (code == IOR && exp == false_rtx)
    return term;
  if (attr_equal_p (exp, term))
    return exp;

  if (GET_CODE (term) == code)
    {
      exp = insert_right_side (code, exp, XEXP (term, 0),
			       insn_code, insn_index);
      exp = insert_right_side (code, exp, XEXP (term, 1),
			       insn_code, insn_index);

      return exp;
    }

  if (GET_CODE (exp) == code)
    {
      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_rtx);
      else
	newexp = exp;
    }
  else
    {
      /* Insert the new term.  */
      newexp = attr_rtx (code, exp, term);
    }

  return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}

/* If we have an expression which AND's a bunch of
	(not (eq_attrq "alternative" "n"))
   terms, we may have covered all or all but one of the possible alternatives.
   If so, we can optimize.  Similarly for IOR's of EQ_ATTR.

   This routine is passed an expression and either AND or IOR.  It returns a
   bitmask indicating which alternatives are mentioned within EXP.  */

static alternative_mask
compute_alternative_mask (rtx exp, enum rtx_code code)
{
  const char *string;
  if (GET_CODE (exp) == code)
    return compute_alternative_mask (XEXP (exp, 0), code)
	   | compute_alternative_mask (XEXP (exp, 1), code);

  else if (code == AND && GET_CODE (exp) == NOT
	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
	   && XSTR (XEXP (exp, 0), 0) == alternative_name)
    string = XSTR (XEXP (exp, 0), 1);

  else if (code == IOR && GET_CODE (exp) == EQ_ATTR
	   && XSTR (exp, 0) == alternative_name)
    string = XSTR (exp, 1);

  else if (GET_CODE (exp) == EQ_ATTR_ALT)
    {
      if (code == AND && XWINT (exp, 1))
	return XWINT (exp, 0);

      if (code == IOR && !XWINT (exp, 1))
	return XWINT (exp, 0);

      return 0;
    }
  else
    return 0;

  if (string[1] == 0)
    return ((alternative_mask) 1) << (string[0] - '0');
  return ((alternative_mask) 1) << atoi (string);
}

/* Given I, a single-bit mask, return RTX to compare the `alternative'
   attribute with the value represented by that bit.  */

static rtx
make_alternative_compare (alternative_mask mask)
{
  return mk_attr_alt (mask);
}

/* If we are processing an (eq_attr "attr" "value") test, we find the value
   of "attr" for this insn code.  From that value, we can compute a test
   showing when the EQ_ATTR will be true.  This routine performs that
   computation.  If a test condition involves an address, we leave the EQ_ATTR
   intact because addresses are only valid for the `length' attribute.

   EXP is the EQ_ATTR expression and ATTR is the attribute to which
   it refers.  VALUE is the value of that attribute for the insn
   corresponding to INSN_CODE and INSN_INDEX.  */

static rtx
evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value,
		  int insn_code, int insn_index)
{
  rtx orexp, andexp;
  rtx right;
  rtx newexp;
  int i;

  while (GET_CODE (value) == ATTR)
    {
      struct attr_value *av = NULL;

      attr = find_attr (&XSTR (value, 0), 0);

      if (insn_code_values)
        {
          struct attr_value_list *iv;
          for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
            if (iv->attr == attr)
              {
                av = iv->av;
                break;
              }
        }
      else
        {
          struct insn_ent *ie;
          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:
          value = av->value;
        }
    }

  switch (GET_CODE (value))
    {
    case CONST_STRING:
      if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
	newexp = true_rtx;
      else
	newexp = false_rtx;
      break;

    case SYMBOL_REF:
      {
	const char *prefix;
	char *string, *p;

	gcc_assert (GET_CODE (exp) == EQ_ATTR);
	prefix = attr->enum_name ? attr->enum_name : attr->name;
	string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
	for (p = string; *p; p++)
	  *p = TOUPPER (*p);

	newexp = attr_rtx (EQ, value,
			   attr_rtx (SYMBOL_REF,
				     DEF_ATTR_STRING (string)));
	break;
      }

    case COND:
      /* 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.  */

      orexp = false_rtx;
      andexp = true_rtx;

      for (i = 0; i < XVECLEN (value, 0); i += 2)
	{
	  rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
						    insn_code, insn_index);

	  right = insert_right_side (AND, andexp, this_cond,
				     insn_code, insn_index);
	  right = insert_right_side (AND, right,
				     evaluate_eq_attr (exp, attr,
						       XVECEXP (value, 0,
								i + 1),
						       insn_code, insn_index),
				     insn_code, insn_index);
	  orexp = insert_right_side (IOR, orexp, right,
				     insn_code, insn_index);

	  /* Add this condition into the AND expression.  */
	  newexp = attr_rtx (NOT, this_cond);
	  andexp = insert_right_side (AND, andexp, newexp,
				      insn_code, insn_index);
	}

      /* Handle the default case.  */
      right = insert_right_side (AND, andexp,
				 evaluate_eq_attr (exp, attr, XEXP (value, 1),
						   insn_code, insn_index),
				 insn_code, insn_index);
      newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
      break;

    default:
      gcc_unreachable ();
    }

  /* If uses an address, must return original expression.  But set the
     ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again.  */

  address_used = 0;
  walk_attr_value (newexp);

  if (address_used)
    {
      if (! ATTR_IND_SIMPLIFIED_P (exp))
	return copy_rtx_unchanging (exp);
      return exp;
    }
  else
    return newexp;
}

/* This routine is called when an AND of a term with a tree of AND's is
   encountered.  If the term or its complement is present in the tree, it
   can be replaced with TRUE or FALSE, respectively.

   Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
   be true and hence are complementary.

   There is one special case:  If we see
	(and (not (eq_attr "att" "v1"))
	     (eq_attr "att" "v2"))
   this can be replaced by (eq_attr "att" "v2").  To do this we need to
   replace the term, not anything in the AND tree.  So we pass a pointer to
   the term.  */

static rtx
simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
{
  rtx left, right;
  rtx newexp;
  rtx temp;
  int left_eliminates_term, right_eliminates_term;

  if (GET_CODE (exp) == AND)
    {
      left  = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
      right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (AND, left, right);

	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
	}
    }

  else if (GET_CODE (exp) == IOR)
    {
      /* For the IOR case, we do the same as above, except that we can
         only eliminate `term' if both sides of the IOR would do so.  */
      temp = *pterm;
      left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
      left_eliminates_term = (temp == true_rtx);

      temp = *pterm;
      right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
      right_eliminates_term = (temp == true_rtx);

      if (left_eliminates_term && right_eliminates_term)
	*pterm = true_rtx;

      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (IOR, left, right);

	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
	}
    }

  /* Check for simplifications.  Do some extra checking here since this
     routine is called so many times.  */

  if (exp == *pterm)
    return true_rtx;

  else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
    return false_rtx;

  else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
    return false_rtx;

  else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
    {
      if (attr_alt_subset_p (*pterm, exp))
	return true_rtx;

      if (attr_alt_subset_of_compl_p (*pterm, exp))
	return false_rtx;

      if (attr_alt_subset_p (exp, *pterm))
	*pterm = true_rtx;

      return exp;
    }

  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
    {
      if (XSTR (exp, 0) != XSTR (*pterm, 0))
	return exp;

      if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
	return true_rtx;
      else
	return false_rtx;
    }

  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
    {
      if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
	return exp;

      if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
	return false_rtx;
      else
	return true_rtx;
    }

  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
    {
      if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
	return exp;

      if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
	return false_rtx;
      else
	*pterm = true_rtx;
    }

  else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
    {
      if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
	return true_rtx;
    }

  else if (GET_CODE (exp) == NOT)
    {
      if (attr_equal_p (XEXP (exp, 0), *pterm))
	return false_rtx;
    }

  else if (GET_CODE (*pterm) == NOT)
    {
      if (attr_equal_p (XEXP (*pterm, 0), exp))
	return false_rtx;
    }

  else if (attr_equal_p (exp, *pterm))
    return true_rtx;

  return exp;
}

/* Similar to `simplify_and_tree', but for IOR trees.  */

static rtx
simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
{
  rtx left, right;
  rtx newexp;
  rtx temp;
  int left_eliminates_term, right_eliminates_term;

  if (GET_CODE (exp) == IOR)
    {
      left  = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
      right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (GET_CODE (exp), left, right);

	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
	}
    }

  else if (GET_CODE (exp) == AND)
    {
      /* For the AND case, we do the same as above, except that we can
         only eliminate `term' if both sides of the AND would do so.  */
      temp = *pterm;
      left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
      left_eliminates_term = (temp == false_rtx);

      temp = *pterm;
      right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
      right_eliminates_term = (temp == false_rtx);

      if (left_eliminates_term && right_eliminates_term)
	*pterm = false_rtx;

      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (GET_CODE (exp), left, right);

	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
	}
    }

  if (attr_equal_p (exp, *pterm))
    return false_rtx;

  else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
    return true_rtx;

  else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
    return true_rtx;

  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
	   && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
    *pterm = false_rtx;

  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
	   && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
    return false_rtx;

  return exp;
}

/* Simplify test expression and use temporary obstack in order to avoid
   memory bloat.  Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
   and avoid unnecessary copying if possible.  */

static rtx
simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
{
  rtx x;
  struct obstack *old;
  if (ATTR_IND_SIMPLIFIED_P (exp))
    return exp;
  old = rtl_obstack;
  rtl_obstack = temp_obstack;
  x = simplify_test_exp (exp, insn_code, insn_index);
  rtl_obstack = old;
  return x;
}

/* Returns true if S1 is a subset of S2.  */

static bool
attr_alt_subset_p (rtx s1, rtx s2)
{
  switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
    {
    case (0 << 1) | 0:
      return !(XWINT (s1, 0) &~ XWINT (s2, 0));

    case (0 << 1) | 1:
      return !(XWINT (s1, 0) & XWINT (s2, 0));

    case (1 << 1) | 0:
      return false;

    case (1 << 1) | 1:
      return !(XWINT (s2, 0) &~ XWINT (s1, 0));

    default:
      gcc_unreachable ();
    }
}

/* Returns true if S1 is a subset of complement of S2.  */

static bool
attr_alt_subset_of_compl_p (rtx s1, rtx s2)
{
  switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
    {
    case (0 << 1) | 0:
      return !(XWINT (s1, 0) & XWINT (s2, 0));

    case (0 << 1) | 1:
      return !(XWINT (s1, 0) & ~XWINT (s2, 0));

    case (1 << 1) | 0:
      return !(XWINT (s2, 0) &~ XWINT (s1, 0));

    case (1 << 1) | 1:
      return false;

    default:
      gcc_unreachable ();
    }
}

/* Return EQ_ATTR_ALT expression representing intersection of S1 and S2.  */

static rtx
attr_alt_intersection (rtx s1, rtx s2)
{
  alternative_mask result;

  switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
    {
    case (0 << 1) | 0:
      result = XWINT (s1, 0) & XWINT (s2, 0);
      break;
    case (0 << 1) | 1:
      result = XWINT (s1, 0) & ~XWINT (s2, 0);
      break;
    case (1 << 1) | 0:
      result = XWINT (s2, 0) & ~XWINT (s1, 0);
      break;
    case (1 << 1) | 1:
      result = XWINT (s1, 0) | XWINT (s2, 0);
      break;
    default:
      gcc_unreachable ();
    }

  return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) & XWINT (s2, 1));
}

/* Return EQ_ATTR_ALT expression representing union of S1 and S2.  */

static rtx
attr_alt_union (rtx s1, rtx s2)
{
  alternative_mask result;

  switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
    {
    case (0 << 1) | 0:
      result = XWINT (s1, 0) | XWINT (s2, 0);
      break;
    case (0 << 1) | 1:
      result = XWINT (s2, 0) & ~XWINT (s1, 0);
      break;
    case (1 << 1) | 0:
      result = XWINT (s1, 0) & ~XWINT (s2, 0);
      break;
    case (1 << 1) | 1:
      result = XWINT (s1, 0) & XWINT (s2, 0);
      break;
    default:
      gcc_unreachable ();
    }

  return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) | XWINT (s2, 1));
}

/* Return EQ_ATTR_ALT expression representing complement of S.  */

static rtx
attr_alt_complement (rtx s)
{
  return attr_rtx (EQ_ATTR_ALT, XWINT (s, 0),
                   ((HOST_WIDE_INT) 1) - XWINT (s, 1));
}

/* Return EQ_ATTR_ALT expression representing set containing elements set
   in E.  */

static rtx
mk_attr_alt (alternative_mask e)
{
  return attr_rtx (EQ_ATTR_ALT, (HOST_WIDE_INT) e, (HOST_WIDE_INT) 0);
}

/* Given an expression, see if it can be simplified for a particular insn
   code based on the values of other attributes being tested.  This can
   eliminate nested get_attr_... calls.

   Note that if an endless recursion is specified in the patterns, the
   optimization will loop.  However, it will do so in precisely the cases where
   an infinite recursion loop could occur during compilation.  It's better that
   it occurs here!  */

static rtx
simplify_test_exp (rtx exp, int insn_code, int insn_index)
{
  rtx left, right;
  class attr_desc *attr;
  struct attr_value *av;
  struct insn_ent *ie;
  struct attr_value_list *iv;
  alternative_mask i;
  rtx newexp = exp;
  bool left_alt, right_alt;

  /* Don't re-simplify something we already simplified.  */
  if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
    return exp;

  switch (GET_CODE (exp))
    {
    case AND:
      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
      if (left == false_rtx)
	return false_rtx;
      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
      if (right == false_rtx)
	return false_rtx;

      if (GET_CODE (left) == EQ_ATTR_ALT
	  && GET_CODE (right) == EQ_ATTR_ALT)
	{
	  exp = attr_alt_intersection (left, right);
	  return simplify_test_exp (exp, insn_code, insn_index);
	}

      /* If either side is an IOR and we have (eq_attr "alternative" ..")
	 present on both sides, apply the distributive law since this will
	 yield simplifications.  */
      if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
	  && compute_alternative_mask (left, IOR)
	  && compute_alternative_mask (right, IOR))
	{
	  if (GET_CODE (left) == IOR)
	    std::swap (left, right);

	  newexp = attr_rtx (IOR,
			     attr_rtx (AND, left, XEXP (right, 0)),
			     attr_rtx (AND, left, XEXP (right, 1)));

	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}

      /* Try with the term on both sides.  */
      right = simplify_and_tree (right, &left, insn_code, insn_index);
      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
	left = simplify_and_tree (left, &right, insn_code, insn_index);

      if (left == false_rtx || right == false_rtx)
	return false_rtx;
      else if (left == true_rtx)
	{
	  return right;
	}
      else if (right == true_rtx)
	{
	  return left;
	}
      /* See if all or all but one of the insn's alternatives are specified
	 in this tree.  Optimize if so.  */

      if (GET_CODE (left) == NOT)
	left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
		    && XSTR (XEXP (left, 0), 0) == alternative_name);
      else
	left_alt = (GET_CODE (left) == EQ_ATTR_ALT
		    && XWINT (left, 1));

      if (GET_CODE (right) == NOT)
	right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
		     && XSTR (XEXP (right, 0), 0) == alternative_name);
      else
	right_alt = (GET_CODE (right) == EQ_ATTR_ALT
		     && XWINT (right, 1));

      if (insn_code >= 0
	  && (GET_CODE (left) == AND
	      || left_alt
	      || GET_CODE (right) == AND
	      || right_alt))
	{
	  i = compute_alternative_mask (exp, AND);
	  if (i & ~insn_alternatives[insn_code])
	    fatal ("invalid alternative specified for pattern number %d",
		   insn_index);

	  /* If all alternatives are excluded, this is false.  */
	  i ^= insn_alternatives[insn_code];
	  if (i == 0)
	    return false_rtx;
	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
	    {
	      /* If just one excluded, AND a comparison with that one to the
		 front of the tree.  The others will be eliminated by
		 optimization.  We do not want to do this if the insn has one
		 alternative and we have tested none of them!  */
	      left = make_alternative_compare (i);
	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
	      newexp = attr_rtx (AND, left, right);

	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	    }
	}

      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (AND, left, right);
	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}
      break;

    case IOR:
      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
      if (left == true_rtx)
	return true_rtx;
      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
      if (right == true_rtx)
	return true_rtx;

      if (GET_CODE (left) == EQ_ATTR_ALT
	  && GET_CODE (right) == EQ_ATTR_ALT)
	{
	  exp = attr_alt_union (left, right);
	  return simplify_test_exp (exp, insn_code, insn_index);
	}

      right = simplify_or_tree (right, &left, insn_code, insn_index);
      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
	left = simplify_or_tree (left, &right, insn_code, insn_index);

      if (right == true_rtx || left == true_rtx)
	return true_rtx;
      else if (left == false_rtx)
	{
	  return right;
	}
      else if (right == false_rtx)
	{
	  return left;
	}

      /* Test for simple cases where the distributive law is useful.  I.e.,
	    convert (ior (and (x) (y))
			 (and (x) (z)))
	    to      (and (x)
			 (ior (y) (z)))
       */

      else if (GET_CODE (left) == AND && GET_CODE (right) == AND
	       && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
	{
	  newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));

	  left = XEXP (left, 0);
	  right = newexp;
	  newexp = attr_rtx (AND, left, right);
	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}

      /* Similarly,
	    convert (ior (and (y) (x))
			 (and (z) (x)))
	    to      (and (ior (y) (z))
			 (x))
         Note that we want the common term to stay at the end.
       */

      else if (GET_CODE (left) == AND && GET_CODE (right) == AND
	       && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
	{
	  newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));

	  left = newexp;
	  right = XEXP (right, 1);
	  newexp = attr_rtx (AND, left, right);
	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}

      /* See if all or all but one of the insn's alternatives are specified
	 in this tree.  Optimize if so.  */

      else if (insn_code >= 0
	       && (GET_CODE (left) == IOR
		   || (GET_CODE (left) == EQ_ATTR_ALT
		       && !XWINT (left, 1))
		   || (GET_CODE (left) == EQ_ATTR
		       && XSTR (left, 0) == alternative_name)
		   || GET_CODE (right) == IOR
		   || (GET_CODE (right) == EQ_ATTR_ALT
		       && !XWINT (right, 1))
		   || (GET_CODE (right) == EQ_ATTR
		       && XSTR (right, 0) == alternative_name)))
	{
	  i = compute_alternative_mask (exp, IOR);
	  if (i & ~insn_alternatives[insn_code])
	    fatal ("invalid alternative specified for pattern number %d",
		   insn_index);

	  /* If all alternatives are included, this is true.  */
	  i ^= insn_alternatives[insn_code];
	  if (i == 0)
	    return true_rtx;
	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
	    {
	      /* If just one excluded, IOR a comparison with that one to the
		 front of the tree.  The others will be eliminated by
		 optimization.  We do not want to do this if the insn has one
		 alternative and we have tested none of them!  */
	      left = make_alternative_compare (i);
	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
	      newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);

	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	    }
	}

      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
	{
	  newexp = attr_rtx (IOR, left, right);
	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}
      break;

    case NOT:
      if (GET_CODE (XEXP (exp, 0)) == NOT)
	{
	  left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
				    insn_code, insn_index);
	  return left;
	}

      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
      if (GET_CODE (left) == NOT)
	return XEXP (left, 0);

      if (left == false_rtx)
	return true_rtx;
      if (left == true_rtx)
	return false_rtx;

      if (GET_CODE (left) == EQ_ATTR_ALT)
	{
	  exp = attr_alt_complement (left);
	  return simplify_test_exp (exp, insn_code, insn_index);
	}

      /* Try to apply De`Morgan's laws.  */
      if (GET_CODE (left) == IOR)
	{
	  newexp = attr_rtx (AND,
			     attr_rtx (NOT, XEXP (left, 0)),
			     attr_rtx (NOT, XEXP (left, 1)));

	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}
      else if (GET_CODE (left) == AND)
	{
	  newexp = attr_rtx (IOR,
			     attr_rtx (NOT, XEXP (left, 0)),
			     attr_rtx (NOT, XEXP (left, 1)));

	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}
      else if (left != XEXP (exp, 0))
	{
	  newexp = attr_rtx (NOT, left);
	}
      break;

    case EQ_ATTR_ALT:
      if (!XWINT (exp, 0))
	return XWINT (exp, 1) ? true_rtx : false_rtx;
      break;

    case EQ_ATTR:
      if (XSTR (exp, 0) == alternative_name)
	{
	  newexp = mk_attr_alt (((alternative_mask) 1)
				<< atoi (XSTR (exp, 1)));
	  break;
	}

      /* 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.  */
      if (insn_code >= 0
	  && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
	{
	  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, attr, av->value,
				    insn_code, insn_index);
	      x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
	      if (attr_rtx_cost (x) < 7)
		return x;
	    }
	}
      break;

    default:
      break;
    }

  /* We have already simplified this expression.  Simplifying it again
     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
      && ! ATTR_IND_SIMPLIFIED_P (newexp))
    return copy_rtx_unchanging (newexp);

  return newexp;
}

/* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
   otherwise return 0.  */

static int
tests_attr_p (rtx p, class 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;
      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 (tests_attr_p (XEXP (p, i), attr))
	    return 1;
	  break;

	case 'E':
	  je = XVECLEN (p, i);
	  for (j = 0; j < je; ++j)
	    if (tests_attr_p (XVECEXP (p, i, j), attr))
	      return 1;
	  break;
	}
    }

  return 0;
}

/* Calculate a topological sorting of all attributes so that
   all attributes only depend on attributes in front of it.
   Place the result in *RET (which is a pointer to an array of
   attr_desc pointers), and return the size of that array.  */

static int
get_attr_order (class attr_desc ***ret)
{
  int i, j;
  int num = 0;
  class attr_desc *attr;
  class attr_desc **all, **sorted;
  char *handled;
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
    for (attr = attrs[i]; attr; attr = attr->next)
      num++;
  all = XNEWVEC (class attr_desc *, num);
  sorted = XNEWVEC (class attr_desc *, num);
  handled = XCNEWVEC (char, num);
  num = 0;
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
    for (attr = attrs[i]; attr; attr = attr->next)
      all[num++] = attr;

  j = 0;
  for (i = 0; i < num; i++)
    if (all[i]->is_const)
      handled[i] = 1, sorted[j++] = all[i];

  /* We have only few attributes hence we can live with the inner
     loop being O(n^2), unlike the normal fast variants of topological
     sorting.  */
  while (j < num)
    {
      for (i = 0; i < num; i++)
	if (!handled[i])
	  {
	    /* Let's see if I depends on anything interesting.  */
	    int k;
	    for (k = 0; k < num; k++)
	      if (!handled[k])
		{
		  struct attr_value *av;
		  for (av = all[i]->first_value; av; av = av->next)
		    if (av->num_insns != 0)
		      if (tests_attr_p (av->value, all[k]))
			break;

		  if (av)
		    /* Something in I depends on K.  */
		    break;
		}
	    if (k == num)
	      {
		/* Nothing in I depended on anything intersting, so
		   it's done.  */
		handled[i] = 1;
		sorted[j++] = all[i];
	      }
	  }
    }

  if (DEBUG)
    for (j = 0; j < num; j++)
      {
	class attr_desc *attr2;
	struct attr_value *av;

	attr = sorted[j];
	fprintf (stderr, "%s depends on: ", attr->name);
	for (i = 0; i < MAX_ATTRS_INDEX; ++i)
	  for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
	    if (!attr2->is_const)
	      for (av = attr->first_value; av; av = av->next)
		if (av->num_insns != 0)
		  if (tests_attr_p (av->value, attr2))
		    {
		      fprintf (stderr, "%s, ", attr2->name);
		      break;
		    }
	fprintf (stderr, "\n");
      }

  free (all);
  *ret = sorted;
  return num;
}

/* Optimize the attribute lists by seeing if we can determine conditional
   values from the known values of other attributes.  This will save subroutine
   calls during the compilation.  NUM_INSN_CODES is the number of unique
   instruction codes.  */

static void
optimize_attrs (int num_insn_codes)
{
  class attr_desc *attr;
  struct attr_value *av;
  struct insn_ent *ie;
  rtx newexp;
  int i;
  struct attr_value_list *ivbuf;
  struct attr_value_list *iv;
  class attr_desc **topsort;
  int topnum;

  /* For each insn code, make a list of all the insn_ent's for it,
     for all values for all attributes.  */

  if (num_insn_ents == 0)
    return;

  /* Make 2 extra elements, for "code" values -2 and -1.  */
  insn_code_values = XCNEWVEC (struct attr_value_list *, num_insn_codes + 2);

  /* Offset the table address so we can index by -2 or -1.  */
  insn_code_values += 2;

  iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);

  /* Create the chain of insn*attr values such that we see dependend
     attributes after their dependencies.  As we use a stack via the
     next pointers start from the end of the topological order.  */
  topnum = get_attr_order (&topsort);
  for (i = topnum - 1; i >= 0; i--)
    for (av = topsort[i]->first_value; av; av = av->next)
      for (ie = av->first_insn; ie; ie = ie->next)
	{
	  iv->attr = topsort[i];
	  iv->av = av;
	  iv->ie = ie;
	  iv->next = insn_code_values[ie->def->insn_code];
	  insn_code_values[ie->def->insn_code] = iv;
	  iv++;
	}
  free (topsort);

  /* Sanity check on num_insn_ents.  */
  gcc_assert (iv == ivbuf + num_insn_ents);

  /* Process one insn code at a time.  */
  for (i = -2; i < num_insn_codes; i++)
    {
      /* 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);

      for (iv = insn_code_values[i]; iv; iv = iv->next)
	{
	  struct obstack *old = rtl_obstack;

	  attr = iv->attr;
	  av = iv->av;
	  ie = iv->ie;
	  if (GET_CODE (av->value) != COND)
	    continue;

	  rtl_obstack = temp_obstack;
	  newexp = av->value;
	  while (GET_CODE (newexp) == COND)
	    {
	      rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
					   ie->def->insn_index);
	      if (newexp2 == newexp)
		break;
	      newexp = newexp2;
	    }

	  rtl_obstack = old;
	  /* If we created a new value for this instruction, and it's
	     cheaper than the old value, and overall cheap, use that
	     one as specific value for the current instruction.
	     The last test is to avoid exploding the get_attr_ function
	     sizes for no much gain.  */
	  if (newexp != av->value
	      && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
	      && attr_rtx_cost (newexp) < 26
	     )
	    {
	      remove_insn_ent (av, ie);
	      av = get_attr_value (ie->def->loc, newexp, attr,
				   ie->def->insn_code);
	      iv->av = av;
	      insert_insn_ent (av, ie);
	    }
	}
    }

  free (ivbuf);
  free (insn_code_values - 2);
  insn_code_values = NULL;
}

/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */

static void
clear_struct_flag (rtx x)
{
  int i;
  int j;
  enum rtx_code code;
  const char *fmt;

  ATTR_CURR_SIMPLIFIED_P (x) = 0;
  if (ATTR_IND_SIMPLIFIED_P (x))
    return;

  code = GET_CODE (x);

  switch (code)
    {
    case REG:
    CASE_CONST_ANY:
    case MATCH_TEST:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case CC0:
    case EQ_ATTR:
    case ATTR_FLAG:
      return;

    default:
      break;
    }

  /* Compare the elements.  If any pair of corresponding elements
     fail to match, return 0 for the whole things.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      switch (fmt[i])
	{
	case 'V':
	case 'E':
	  for (j = 0; j < XVECLEN (x, i); j++)
	    clear_struct_flag (XVECEXP (x, i, j));
	  break;

	case 'e':
	  clear_struct_flag (XEXP (x, i));
	  break;
	}
    }
}

/* Add attribute value NAME to the beginning of ATTR's list.  */

static void
add_attr_value (class attr_desc *attr, const char *name)
{
  struct attr_value *av;

  av = oballoc (struct attr_value);
  av->value = attr_rtx (CONST_STRING, name);
  av->next = attr->first_value;
  attr->first_value = av;
  av->first_insn = NULL;
  av->num_insns = 0;
  av->has_asm_insn = 0;
}

/* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR.  */

static void
gen_attr (md_rtx_info *info)
{
  struct enum_type *et;
  struct enum_value *ev;
  class attr_desc *attr;
  const char *name_ptr;
  char *p;
  rtx def = info->def;

  /* Make a new attribute structure.  Check for duplicate by looking at
     attr->default_val, since it is initialized by this routine.  */
  attr = find_attr (&XSTR (def, 0), 1);
  if (attr->default_val)
    {
      error_at (info->loc, "duplicate definition for attribute %s",
		attr->name);
      message_at (attr->loc, "previous definition");
      return;
    }
  attr->loc = info->loc;

  if (GET_CODE (def) == DEFINE_ENUM_ATTR)
    {
      attr->enum_name = XSTR (def, 1);
      et = rtx_reader_ptr->lookup_enum_type (XSTR (def, 1));
      if (!et || !et->md_p)
	error_at (info->loc, "No define_enum called `%s' defined",
		  attr->name);
      if (et)
	for (ev = et->values; ev; ev = ev->next)
	  add_attr_value (attr, ev->name);
    }
  else if (*XSTR (def, 1) == '\0')
    attr->is_numeric = 1;
  else
    {
      name_ptr = XSTR (def, 1);
      while ((p = next_comma_elt (&name_ptr)) != NULL)
	add_attr_value (attr, p);
    }

  if (GET_CODE (XEXP (def, 2)) == CONST)
    {
      attr->is_const = 1;
      if (attr->is_numeric)
	error_at (info->loc,
		  "constant attributes may not take numeric values");

      /* Get rid of the CONST node.  It is allowed only at top-level.  */
      XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
    }

  if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
    error_at (info->loc, "`length' attribute must take numeric values");

  /* Set up the default value.  */
  XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
  attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
}

/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
   alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
   number of alternatives as this should be checked elsewhere.  */

static int
count_alternatives (rtx exp)
{
  int i, j, n;
  const char *fmt;

  if (GET_CODE (exp) == MATCH_OPERAND)
    return n_comma_elts (XSTR (exp, 2));

  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
    switch (*fmt++)
      {
      case 'e':
      case 'u':
	n = count_alternatives (XEXP (exp, i));
	if (n)
	  return n;
	break;

      case 'E':
      case 'V':
	if (XVEC (exp, i) != NULL)
	  for (j = 0; j < XVECLEN (exp, i); j++)
	    {
	      n = count_alternatives (XVECEXP (exp, i, j));
	      if (n)
		return n;
	    }
      }

  return 0;
}

/* Returns nonzero if the given expression contains an EQ_ATTR with the
   `alternative' attribute.  */

static int
compares_alternatives_p (rtx exp)
{
  int i, j;
  const char *fmt;

  if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
    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 (compares_alternatives_p (XEXP (exp, i)))
	  return 1;
	break;

      case 'E':
	for (j = 0; j < XVECLEN (exp, i); j++)
	  if (compares_alternatives_p (XVECEXP (exp, i, j)))
	    return 1;
	break;
      }

  return 0;
}

/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */

static void
gen_insn (md_rtx_info *info)
{
  class insn_def *id;
  rtx def = info->def;

  id = oballoc (class insn_def);
  id->next = defs;
  defs = id;
  id->def = def;
  id->loc = info->loc;

  switch (GET_CODE (def))
    {
    case DEFINE_INSN:
      id->insn_code = info->index;
      id->insn_index = insn_index_number;
      id->num_alternatives = count_alternatives (def);
      if (id->num_alternatives == 0)
	id->num_alternatives = 1;
      id->vec_idx = 4;
      break;

    case DEFINE_PEEPHOLE:
      id->insn_code = info->index;
      id->insn_index = insn_index_number;
      id->num_alternatives = count_alternatives (def);
      if (id->num_alternatives == 0)
	id->num_alternatives = 1;
      id->vec_idx = 3;
      break;

    case DEFINE_ASM_ATTRIBUTES:
      id->insn_code = -1;
      id->insn_index = -1;
      id->num_alternatives = 1;
      id->vec_idx = 0;
      got_define_asm_attributes = 1;
      break;

    default:
      gcc_unreachable ();
    }
}

/* Process a DEFINE_DELAY.  Validate the vector length, check if annul
   true or annul false is specified, and make a `struct delay_desc'.  */

static void
gen_delay (md_rtx_info *info)
{
  class delay_desc *delay;
  int i;

  rtx def = info->def;
  if (XVECLEN (def, 1) % 3 != 0)
    {
      error_at (info->loc, "number of elements in DEFINE_DELAY must"
		" be multiple of three");
      return;
    }

  for (i = 0; i < XVECLEN (def, 1); i += 3)
    {
      if (XVECEXP (def, 1, i + 1))
	have_annul_true = 1;
      if (XVECEXP (def, 1, i + 2))
	have_annul_false = 1;
    }

  delay = oballoc (class delay_desc);
  delay->def = def;
  delay->num = ++num_delays;
  delay->next = delays;
  delay->loc = info->loc;
  delays = delay;
}

/* Names of attributes that could be possibly cached.  */
static const char *cached_attrs[32];
/* Number of such attributes.  */
static int cached_attr_count;
/* Bitmasks of possibly cached attributes.  */
static unsigned int attrs_seen_once, attrs_seen_more_than_once;
static unsigned int attrs_to_cache;
static unsigned int attrs_cached_inside, attrs_cached_after;

/* Finds non-const attributes that could be possibly cached.
   When create is TRUE, fills in cached_attrs array.
   Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
   bitmasks.  */

static void
find_attrs_to_cache (rtx exp, bool create)
{
  int i;
  const char *name;
  class attr_desc *attr;

  if (exp == NULL)
    return;

  switch (GET_CODE (exp))
    {
    case NOT:
      if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
	find_attrs_to_cache (XEXP (exp, 0), create);
      return;

    case EQ_ATTR:
      name = XSTR (exp, 0);
      if (name == alternative_name)
	return;
      for (i = 0; i < cached_attr_count; i++)
	if (name == cached_attrs[i])
	  {
	    if ((attrs_seen_once & (1U << i)) != 0)
	      attrs_seen_more_than_once |= (1U << i);
	    else
	      attrs_seen_once |= (1U << i);
	    return;
	  }
      if (!create)
	return;
      attr = find_attr (&name, 0);
      gcc_assert (attr);
      if (attr->is_const)
	return;
      if (cached_attr_count == 32)
	return;
      cached_attrs[cached_attr_count] = XSTR (exp, 0);
      attrs_seen_once |= (1U << cached_attr_count);
      cached_attr_count++;
      return;

    case AND:
    case IOR:
      find_attrs_to_cache (XEXP (exp, 0), create);
      find_attrs_to_cache (XEXP (exp, 1), create);
      return;

    case COND:
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	find_attrs_to_cache (XVECEXP (exp, 0, i), create);
      return;

    default:
      return;
    }
}

/* Given a piece of RTX, print a C expression to test its truth value to OUTF.
   We use AND and IOR both for logical and bit-wise operations, so
   interpret them as logical unless they are inside a comparison expression.

   An outermost pair of parentheses is emitted around this C expression unless
   EMIT_PARENS is false.  */

/* Interpret AND/IOR as bit-wise operations instead of logical.  */
#define FLG_BITWISE		1
/* Set if cached attribute will be known initialized in else block after
   this condition.  This is true for LHS of toplevel && and || and
   even for RHS of ||, but not for RHS of &&.  */
#define FLG_AFTER		2
/* Set if cached attribute will be known initialized in then block after
   this condition.  This is true for LHS of toplevel && and || and
   even for RHS of &&, but not for RHS of ||.  */
#define FLG_INSIDE		4
/* Cleared when an operand of &&.  */
#define FLG_OUTSIDE_AND		8

static unsigned int
write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
		 bool emit_parens = true)
{
  int comparison_operator = 0;
  RTX_CODE code;
  class attr_desc *attr;

  if (emit_parens)
    fprintf (outf, "(");

  code = GET_CODE (exp);
  switch (code)
    {
    /* Binary operators.  */
    case GEU: case GTU:
    case LEU: case LTU:
      fprintf (outf, "(unsigned) ");
      /* Fall through.  */

    case EQ: case NE:
    case GE: case GT:
    case LE: case LT:
      comparison_operator = FLG_BITWISE;
      /* FALLTHRU */

    case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
    case AND:    case IOR:    case XOR:
    case ASHIFT: case LSHIFTRT: case ASHIFTRT:
      if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
	{
	  flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
	  write_test_expr (outf, XEXP (exp, 0), attrs_cached,
			   flags | comparison_operator);
	}
      else
	{
	  if (code == AND)
	    flags &= ~FLG_OUTSIDE_AND;
	  if (GET_CODE (XEXP (exp, 0)) == code
	      || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
	      || (GET_CODE (XEXP (exp, 0)) == NOT
		  && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
	    attrs_cached
	      = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
	  else
	    write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
	}
      switch (code)
	{
	case EQ:
	  fprintf (outf, " == ");
	  break;
	case NE:
	  fprintf (outf, " != ");
	  break;
	case GE:
	  fprintf (outf, " >= ");
	  break;
	case GT:
	  fprintf (outf, " > ");
	  break;
	case GEU:
	  fprintf (outf, " >= (unsigned) ");
	  break;
	case GTU:
	  fprintf (outf, " > (unsigned) ");
	  break;
	case LE:
	  fprintf (outf, " <= ");
	  break;
	case LT:
	  fprintf (outf, " < ");
	  break;
	case LEU:
	  fprintf (outf, " <= (unsigned) ");
	  break;
	case LTU:
	  fprintf (outf, " < (unsigned) ");
	  break;
	case PLUS:
	  fprintf (outf, " + ");
	  break;
	case MINUS:
	  fprintf (outf, " - ");
	  break;
	case MULT:
	  fprintf (outf, " * ");
	  break;
	case DIV:
	  fprintf (outf, " / ");
	  break;
	case MOD:
	  fprintf (outf, " %% ");
	  break;
	case AND:
	  if (flags & FLG_BITWISE)
	    fprintf (outf, " & ");
	  else
	    fprintf (outf, " && ");
	  break;
	case IOR:
	  if (flags & FLG_BITWISE)
	    fprintf (outf, " | ");
	  else
	    fprintf (outf, " || ");
	  break;
	case XOR:
	  fprintf (outf, " ^ ");
	  break;
	case ASHIFT:
	  fprintf (outf, " << ");
	  break;
	case LSHIFTRT:
	case ASHIFTRT:
	  fprintf (outf, " >> ");
	  break;
	default:
	  gcc_unreachable ();
	}

      if (code == AND)
	{
	  /* For if (something && (cached_x = get_attr_x (insn)) == X)
	     cached_x is only known to be initialized in then block.  */
	  flags &= ~FLG_AFTER;
	}
      else if (code == IOR)
	{
	  if (flags & FLG_OUTSIDE_AND)
	    /* For if (something || (cached_x = get_attr_x (insn)) == X)
	       cached_x is only known to be initialized in else block
	       and else if conditions.  */
	    flags &= ~FLG_INSIDE;
	  else
	    /* For if ((something || (cached_x = get_attr_x (insn)) == X)
		       && something_else)
	       cached_x is not know to be initialized anywhere.  */
	    flags &= ~(FLG_AFTER | FLG_INSIDE);
	}
      if ((code == AND || code == IOR)
	  && (GET_CODE (XEXP (exp, 1)) == code
	      || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
	      || (GET_CODE (XEXP (exp, 1)) == NOT
		  && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
	{
	  bool need_parens = true;

	  /* No need to emit parentheses around the right-hand operand if we are
	     continuing a chain of && or || (or & or |).  */
	  if (GET_CODE (XEXP (exp, 1)) == code)
	    need_parens = false;

	  attrs_cached
	    = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags,
			       need_parens);
	}
      else
	write_test_expr (outf, XEXP (exp, 1), attrs_cached,
			 flags | comparison_operator);
      break;

    case NOT:
      /* Special-case (not (eq_attrq "alternative" "x")) */
      if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
	{
	  if (XSTR (XEXP (exp, 0), 0) == alternative_name)
	    {
	      fprintf (outf, "which_alternative != %s",
		       XSTR (XEXP (exp, 0), 1));
	      break;
	    }

	  fprintf (outf, "! ");
	  attrs_cached =
	    write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
	  break;
	}

      /* Otherwise, fall through to normal unary operator.  */
      gcc_fallthrough ();

    /* Unary operators.  */
    case ABS:  case NEG:
      switch (code)
	{
	case NOT:
	  if (flags & FLG_BITWISE)
	    fprintf (outf, "~ ");
	  else
	    fprintf (outf, "! ");
	  break;
	case ABS:
	  fprintf (outf, "abs ");
	  break;
	case NEG:
	  fprintf (outf, "-");
	  break;
	default:
	  gcc_unreachable ();
	}

      flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
      write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
      break;

    case EQ_ATTR_ALT:
	{
	  alternative_mask set = XWINT (exp, 0);
	  int bit = 0;

	  if (flags & FLG_BITWISE)
	    fatal ("EQ_ATTR_ALT not valid inside comparison");

	  if (!set)
	    fatal ("Empty EQ_ATTR_ALT should be optimized out");

	  if (!(set & (set - 1)))
	    {
	      if (!(set & 0xffffffff))
		{
		  bit += 32;
		  set >>= 32;
		}
	      if (!(set & 0xffff))
		{
		  bit += 16;
		  set >>= 16;
		}
	      if (!(set & 0xff))
		{
		  bit += 8;
		  set >>= 8;
		}
	      if (!(set & 0xf))
		{
		  bit += 4;
		  set >>= 4;
		}
	      if (!(set & 0x3))
		{
		  bit += 2;
		  set >>= 2;
		}
	      if (!(set & 1))
		bit++;

	      fprintf (outf, "which_alternative %s= %d",
		       XWINT (exp, 1) ? "!" : "=", bit);
	    }
	  else
	    {
	      fprintf (outf, "%s((1ULL << which_alternative) & %#" PRIx64
			     "ULL)",
		       XWINT (exp, 1) ? "!" : "", set);
	    }
	}
      break;

    /* Comparison test of an attribute with a value.  Most of these will
       have been removed by optimization.   Handle "alternative"
       specially and give error if EQ_ATTR present inside a comparison.  */
    case EQ_ATTR:
      if (flags & FLG_BITWISE)
	fatal ("EQ_ATTR not valid inside comparison");

      if (XSTR (exp, 0) == alternative_name)
	{
	  fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
	  break;
	}

      attr = find_attr (&XSTR (exp, 0), 0);
      gcc_assert (attr);

      /* Now is the time to expand the value of a constant attribute.  */
      if (attr->is_const)
	{
	  write_test_expr (outf,
			   evaluate_eq_attr (exp, attr,
					     attr->default_val->value,
					     -2, -2),
			   attrs_cached, 0);
	}
      else
	{
	  int i;
	  for (i = 0; i < cached_attr_count; i++)
	    if (attr->name == cached_attrs[i])
	      break;
	  if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
	    fprintf (outf, "cached_%s", attr->name);
	  else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
	    {
	      fprintf (outf, "(cached_%s = get_attr_%s (insn))",
		      attr->name, attr->name);
	      if (flags & FLG_AFTER)
		attrs_cached_after |= (1U << i);
	      if (flags & FLG_INSIDE)
		attrs_cached_inside |= (1U << i);
	      attrs_cached |= (1U << i);
	    }
	  else
	    fprintf (outf, "get_attr_%s (insn)", attr->name);
	  fprintf (outf, " == ");
	  write_attr_valueq (outf, attr, XSTR (exp, 1));
	}
      break;

    /* Comparison test of flags for define_delays.  */
    case ATTR_FLAG:
      if (flags & FLG_BITWISE)
	fatal ("ATTR_FLAG not valid inside comparison");
      fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
      break;

    /* See if an operand matches a predicate.  */
    case MATCH_OPERAND:
      /* If only a mode is given, just ensure the mode matches the operand.
	 If neither a mode nor predicate is given, error.  */
      if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
	{
	  if (GET_MODE (exp) == VOIDmode)
	    fatal ("null MATCH_OPERAND specified as test");
	  else
	    fprintf (outf, "GET_MODE (operands[%d]) == %smode",
		     XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
	}
      else
	fprintf (outf, "%s (operands[%d], %smode)",
		 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
      break;

    /* Constant integer.  */
    case CONST_INT:
      fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
      break;

    case MATCH_TEST:
      rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
      if (flags & FLG_BITWISE)
	fprintf (outf, " != 0");
      break;

    /* A random C expression.  */
    case SYMBOL_REF:
      rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
      break;

    /* The address of the branch target.  */
    case MATCH_DUP:
      fprintf (outf,
	       "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
	       XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
      break;

    case PC:
      /* The address of the current insn.  We implement this actually as the
	 address of the current insn for backward branches, but the last
	 address of the next insn for forward branches, and both with
	 adjustments that account for the worst-case possible stretching of
	 intervening alignments between this insn and its destination.  */
      fprintf (outf, "insn_current_reference_address (insn)");
      break;

    case CONST_STRING:
      fprintf (outf, "%s", XSTR (exp, 0));
      break;

    case IF_THEN_ELSE:
      write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
      fprintf (outf, " ? ");
      write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
      fprintf (outf, " : ");
      write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
      break;

    default:
      fatal ("bad RTX code `%s' in attribute calculation\n",
	     GET_RTX_NAME (code));
    }

  if (emit_parens)
    fprintf (outf, ")");

  return attrs_cached;
}

/* Given an attribute value expression, return the maximum value that
   might be evaluated.  Return INT_MAX if the value can't be
   calculated by this function.  */

static int
max_attr_value (rtx exp)
{
  int current_max;
  int i, n;

  switch (GET_CODE (exp))
    {
    case CONST_STRING:
      current_max = atoi (XSTR (exp, 0));
      break;

    case CONST_INT:
      current_max = INTVAL (exp);
      break;

    case PLUS:
      current_max = max_attr_value (XEXP (exp, 0));
      if (current_max != INT_MAX)
	{
	  n = current_max;
	  current_max = max_attr_value (XEXP (exp, 1));
	  if (current_max != INT_MAX)
	    current_max += n;
	}
      break;

    case MINUS:
      current_max = max_attr_value (XEXP (exp, 0));
      if (current_max != INT_MAX)
	{
	  n = current_max;
	  current_max = min_attr_value (XEXP (exp, 1));
	  if (current_max != INT_MAX)
	    current_max = n - current_max;
	}
      break;

    case MULT:
      current_max = max_attr_value (XEXP (exp, 0));
      if (current_max != INT_MAX)
	{
	  n = current_max;
	  current_max = max_attr_value (XEXP (exp, 1));
	  if (current_max != INT_MAX)
	    current_max *= n;
	}
      break;

    case COND:
      current_max = max_attr_value (XEXP (exp, 1));
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	{
	  n = max_attr_value (XVECEXP (exp, 0, i + 1));
	  if (n > current_max)
	    current_max = n;
	}
      break;

    case IF_THEN_ELSE:
      current_max = max_attr_value (XEXP (exp, 1));
      n = max_attr_value (XEXP (exp, 2));
      if (n > current_max)
	current_max = n;
      break;

    default:
      current_max = INT_MAX;
      break;
    }

  return current_max;
}

/* Given an attribute value expression, return the minimum value that
   might be evaluated.  Return INT_MAX if the value can't be
   calculated by this function.  Note that when this function can
   calculate one value inside IF_THEN_ELSE or some but not all values
   inside COND, then it returns the minimum among those values it can
   calculate.  */

static int
min_attr_value (rtx exp)
{
  int current_min;
  int i, n;

  switch (GET_CODE (exp))
    {
    case CONST_STRING:
      current_min = atoi (XSTR (exp, 0));
      break;

    case CONST_INT:
      current_min = INTVAL (exp);
      break;

    case PLUS:
      current_min = min_attr_value (XEXP (exp, 0));
      if (current_min != INT_MAX)
	{
	  n = current_min;
	  current_min = min_attr_value (XEXP (exp, 1));
	  if (current_min != INT_MAX)
	    current_min += n;
	}
      break;

    case MINUS:
      current_min = min_attr_value (XEXP (exp, 0));
      if (current_min != INT_MAX)
	{
	  n = current_min;
	  current_min = max_attr_value (XEXP (exp, 1));
	  if (current_min != INT_MAX)
	    current_min = n - current_min;
	}
      break;

    case MULT:
      current_min = min_attr_value (XEXP (exp, 0));
      if (current_min != INT_MAX)
	{
	  n = current_min;
	  current_min = min_attr_value (XEXP (exp, 1));
	  if (current_min != INT_MAX)
	    current_min *= n;
	}
      break;

    case COND:
      current_min = min_attr_value (XEXP (exp, 1));
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	{
	  n = min_attr_value (XVECEXP (exp, 0, i + 1));
	  if (n < current_min)
	    current_min = n;
	}
      break;

    case IF_THEN_ELSE:
      current_min = min_attr_value (XEXP (exp, 1));
      n = min_attr_value (XEXP (exp, 2));
      if (n < current_min)
	current_min = n;
      break;

    default:
      current_min = INT_MAX;
      break;
    }

  return current_min;
}

/* Given an attribute value expression, return the alignment of values.
   Return 0 if EXP is known to be zero, and 1 if the value can't be
   calculated by this function.  */

static unsigned int
attr_value_alignment (rtx exp)
{
  unsigned int current_or;
  int i;

  switch (GET_CODE (exp))
    {
    case CONST_STRING:
      current_or = atoi (XSTR (exp, 0));
      break;

    case CONST_INT:
      current_or = INTVAL (exp);
      break;

    case PLUS:
    case MINUS:
      current_or = attr_value_alignment (XEXP (exp, 0));
      current_or |= attr_value_alignment (XEXP (exp, 1));
      break;

    case MULT:
      current_or = attr_value_alignment (XEXP (exp, 0));
      current_or *= attr_value_alignment (XEXP (exp, 1));
      break;

    case COND:
      current_or = attr_value_alignment (XEXP (exp, 1));
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
	current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1));
      break;

    case IF_THEN_ELSE:
      current_or = attr_value_alignment (XEXP (exp, 1));
      current_or |= attr_value_alignment (XEXP (exp, 2));
      break;

    default:
      current_or = 1;
      break;
    }

  return current_or & -current_or;
}

/* Scan an attribute value, possibly a conditional, and record what actions
   will be required to do any conditional tests in it.

   Specifically, set
	`must_extract'	  if we need to extract the insn operands
	`must_constrain'  if we must compute `which_alternative'
	`address_used'	  if an address expression was used
	`length_used'	  if an (eq_attr "length" ...) was used
 */

static void
walk_attr_value (rtx exp)
{
  int i, j;
  const char *fmt;
  RTX_CODE code;

  if (exp == NULL)
    return;

  code = GET_CODE (exp);
  switch (code)
    {
    case SYMBOL_REF:
      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.  */
	must_extract = must_constrain = 1;
      return;

    case MATCH_OPERAND:
      must_extract = 1;
      return;

    case MATCH_TEST:
    case EQ_ATTR_ALT:
      must_extract = must_constrain = 1;
      break;

    case EQ_ATTR:
      if (XSTR (exp, 0) == alternative_name)
	must_extract = must_constrain = 1;
      else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
	length_used = 1;
      return;

    case MATCH_DUP:
      must_extract = 1;
      address_used = 1;
      return;

    case PC:
      address_used = 1;
      return;

    case ATTR_FLAG:
      return;

    default:
      break;
    }

  for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
    switch (*fmt++)
      {
      case 'e':
      case 'u':
	walk_attr_value (XEXP (exp, i));
	break;

      case 'E':
	if (XVEC (exp, i) != NULL)
	  for (j = 0; j < XVECLEN (exp, i); j++)
	    walk_attr_value (XVECEXP (exp, i, j));
	break;
      }
}

/* Write out a function to obtain the attribute for a given INSN.  */

static void
write_attr_get (FILE *outf, class attr_desc *attr)
{
  struct attr_value *av, *common_av;
  int i, j;

  /* Find the most used attribute value.  Handle that as the `default' of the
     switch we will generate.  */
  common_av = find_most_used (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->enum_name)
    fprintf (outf, "enum %s\n", attr->enum_name);
  else if (!attr->is_numeric)
    fprintf (outf, "enum attr_%s\n", attr->name);
  else
    fprintf (outf, "int\n");

  /* 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] == '*')
    fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
  else if (attr->is_const == 0)
    fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
  else
    {
      fprintf (outf, "get_attr_%s (void)\n", attr->name);
      fprintf (outf, "{\n");

      for (av = attr->first_value; av; av = av->next)
	if (av->num_insns == 1)
	  write_attr_set (outf, attr, 2, av->value, "return", ";",
			  true_rtx, av->first_insn->def->insn_code,
			  av->first_insn->def->insn_index, 0);
	else if (av->num_insns != 0)
	  write_attr_set (outf, attr, 2, av->value, "return", ";",
			  true_rtx, -2, 0, 0);

      fprintf (outf, "}\n\n");
      return;
    }

  fprintf (outf, "{\n");

  /* Find attributes that are worth caching in the conditions.  */
  cached_attr_count = 0;
  attrs_seen_more_than_once = 0;
  for (av = attr->first_value; av; av = av->next)
    {
      attrs_seen_once = 0;
      find_attrs_to_cache (av->value, true);
    }
  /* Remove those that aren't worth caching from the array.  */
  for (i = 0, j = 0; i < cached_attr_count; i++)
    if ((attrs_seen_more_than_once & (1U << i)) != 0)
      {
	const char *name = cached_attrs[i];
	class attr_desc *cached_attr;
	if (i != j)
	  cached_attrs[j] = name;
	cached_attr = find_attr (&name, 0);
	gcc_assert (cached_attr && cached_attr->is_const == 0);
	if (cached_attr->enum_name)
	  fprintf (outf, "  enum %s", cached_attr->enum_name);
	else if (!cached_attr->is_numeric)
	  fprintf (outf, "  enum attr_%s", cached_attr->name);
	else
	  fprintf (outf, "  int");
	fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
	j++;
      }
  cached_attr_count = j;
  if (cached_attr_count)
    fprintf (outf, "\n");

  fprintf (outf, "  switch (recog_memoized (insn))\n");
  fprintf (outf, "    {\n");

  for (av = attr->first_value; av; av = av->next)
    if (av != common_av)
      write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);

  write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
  fprintf (outf, "    }\n}\n\n");
  cached_attr_count = 0;
}

/* Given an AND tree of known true terms (because we are inside an `if' with
   that as the condition or are in an `else' clause) and an expression,
   replace any known true terms with TRUE.  Use `simplify_and_tree' to do
   the bulk of the work.  */

static rtx
eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
{
  rtx term;

  known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);

  if (GET_CODE (known_true) == AND)
    {
      exp = eliminate_known_true (XEXP (known_true, 0), exp,
				  insn_code, insn_index);
      exp = eliminate_known_true (XEXP (known_true, 1), exp,
				  insn_code, insn_index);
    }
  else
    {
      term = known_true;
      exp = simplify_and_tree (exp, &term, insn_code, insn_index);
    }

  return exp;
}

/* Write out a series of tests and assignment statements to perform tests and
   sets of an attribute value.  We are passed an indentation amount and prefix
   and suffix strings to write around each attribute value (e.g., "return"
   and ";").  */

static void
write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
		const char *prefix, const char *suffix, rtx known_true,
		int insn_code, int insn_index, unsigned int attrs_cached)
{
  if (GET_CODE (value) == COND)
    {
      /* Assume the default value will be the default of the COND unless we
	 find an always true expression.  */
      rtx default_val = XEXP (value, 1);
      rtx our_known_true = known_true;
      rtx newexp;
      int first_if = 1;
      int i;

      if (cached_attr_count)
	{
	  attrs_seen_once = 0;
	  attrs_seen_more_than_once = 0;
	  for (i = 0; i < XVECLEN (value, 0); i += 2)
	    find_attrs_to_cache (XVECEXP (value, 0, i), false);
	  attrs_to_cache |= attrs_seen_more_than_once;
	}

      for (i = 0; i < XVECLEN (value, 0); i += 2)
	{
	  rtx testexp;
	  rtx inner_true;

	  /* Reset our_known_true after some time to not accumulate
	     too much cruft (slowing down genattrtab).  */
	  if ((i & 31) == 0)
	    our_known_true = known_true;
	  testexp = eliminate_known_true (our_known_true,
					  XVECEXP (value, 0, i),
					  insn_code, insn_index);
	  newexp = attr_rtx (NOT, testexp);
	  newexp = insert_right_side (AND, our_known_true, newexp,
				      insn_code, insn_index);

	  /* If the test expression is always true or if the next `known_true'
	     expression is always false, this is the last case, so break
	     out and let this value be the `else' case.  */
	  if (testexp == true_rtx || newexp == false_rtx)
	    {
	      default_val = XVECEXP (value, 0, i + 1);
	      break;
	    }

	  /* Compute the expression to pass to our recursive call as being
	     known true.  */
	  inner_true = insert_right_side (AND, our_known_true,
					  testexp, insn_code, insn_index);

	  /* If this is always false, skip it.  */
	  if (inner_true == false_rtx)
	    continue;

	  attrs_cached_inside = attrs_cached;
	  attrs_cached_after = attrs_cached;
	  write_indent (outf, indent);
	  fprintf (outf, "%sif ", first_if ? "" : "else ");
	  first_if = 0;
	  write_test_expr (outf, testexp, attrs_cached,
			   (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
	  attrs_cached = attrs_cached_after;
	  fprintf (outf, "\n");
	  write_indent (outf, indent + 2);
	  fprintf (outf, "{\n");

	  write_attr_set (outf, attr, indent + 4,
			  XVECEXP (value, 0, i + 1), prefix, suffix,
			  inner_true, insn_code, insn_index,
			  attrs_cached_inside);
	  write_indent (outf, indent + 2);
	  fprintf (outf, "}\n");
	  our_known_true = newexp;
	}

      if (! first_if)
	{
	  write_indent (outf, indent);
	  fprintf (outf, "else\n");
	  write_indent (outf, indent + 2);
	  fprintf (outf, "{\n");
	}

      write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
		      prefix, suffix, our_known_true, insn_code, insn_index,
		      attrs_cached);

      if (! first_if)
	{
	  write_indent (outf, indent + 2);
	  fprintf (outf, "}\n");
	}
    }
  else
    {
      write_indent (outf, indent);
      fprintf (outf, "%s ", prefix);
      write_attr_value (outf, attr, value);
      fprintf (outf, "%s\n", suffix);
    }
}

/* Write a series of case statements for every instruction in list IE.
   INDENT is the amount of indentation to write before each case.  */

static void
write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
{
  for (; ie != 0; ie = ie->next)
    if (ie->def->insn_code != -1)
      {
	write_indent (outf, indent);
	if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
	  fprintf (outf, "case %d:  /* define_peephole, %s:%d */\n",
		   ie->def->insn_code, ie->def->loc.filename,
		   ie->def->loc.lineno);
	else
	  fprintf (outf, "case %d:  /* %s */\n",
		   ie->def->insn_code, XSTR (ie->def->def, 0));
      }
}

/* Write out the computation for one attribute value.  */

static void
write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
		 int write_case_lines, const char *prefix, const char *suffix,
		 int indent, rtx known_true)
{
  if (av->num_insns == 0)
    return;

  if (av->has_asm_insn)
    {
      write_indent (outf, indent);
      fprintf (outf, "case -1:\n");
      write_indent (outf, indent + 2);
      fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
      write_indent (outf, indent + 2);
      fprintf (outf, "    && asm_noperands (PATTERN (insn)) < 0)\n");
      write_indent (outf, indent + 2);
      fprintf (outf, "  fatal_insn_not_found (insn);\n");
      write_indent (outf, indent + 2);
      fprintf (outf, "/* FALLTHRU */\n");
    }

  if (write_case_lines)
    write_insn_cases (outf, av->first_insn, indent);
  else
    {
      write_indent (outf, indent);
      fprintf (outf, "default:\n");
    }

  /* See what we have to do to output this value.  */
  must_extract = must_constrain = address_used = 0;
  walk_attr_value (av->value);

  if (must_constrain)
    {
      write_indent (outf, indent + 2);
      fprintf (outf, "extract_constrain_insn_cached (insn);\n");
    }
  else if (must_extract)
    {
      write_indent (outf, indent + 2);
      fprintf (outf, "extract_insn_cached (insn);\n");
    }

  attrs_to_cache = 0;
  if (av->num_insns == 1)
    write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
		    known_true, av->first_insn->def->insn_code,
		    av->first_insn->def->insn_index, 0);
  else
    write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
		    known_true, -2, 0, 0);

  if (strncmp (prefix, "return", 6))
    {
      write_indent (outf, indent + 2);
      fprintf (outf, "break;\n");
    }
  fprintf (outf, "\n");
}

/* Utilities to write in various forms.  */

static void
write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
{
  if (attr->is_numeric)
    {
      int num = atoi (s);

      fprintf (outf, "%d", num);

      if (num > 9 || num < 0)
	fprintf (outf, " /* %#x */", num);
    }
  else
    {
      write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
      fprintf (outf, "_");
      write_upcase (outf, s);
    }
}

static void
write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
{
  int op;

  switch (GET_CODE (value))
    {
    case CONST_STRING:
      write_attr_valueq (outf, attr, XSTR (value, 0));
      break;

    case CONST_INT:
      fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
      break;

    case SYMBOL_REF:
      rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0));
      break;

    case ATTR:
      {
	class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
	if (attr->enum_name)
	  fprintf (outf, "(enum %s)", attr->enum_name);
	else if (!attr->is_numeric)
	  fprintf (outf, "(enum attr_%s)", attr->name);
	else if (!attr2->is_numeric)
	  fprintf (outf, "(int)");

	fprintf (outf, "get_attr_%s (%s)", attr2->name,
		 (attr2->is_const ? "" : "insn"));
      }
      break;

    case PLUS:
      op = '+';
      goto do_operator;
    case MINUS:
      op = '-';
      goto do_operator;
    case MULT:
      op = '*';
      goto do_operator;
    case DIV:
      op = '/';
      goto do_operator;
    case MOD:
      op = '%';
      goto do_operator;

    do_operator:
      fprintf (outf, "(");
      write_attr_value (outf, attr, XEXP (value, 0));
      fprintf (outf, " %c ", op);
      write_attr_value (outf, attr, XEXP (value, 1));
      fprintf (outf, ")");
      break;

    case IF_THEN_ELSE:
      fprintf (outf, "(");
      write_test_expr (outf, XEXP (value, 0), 0, 0, false);
      fprintf (outf, " ? ");
      write_attr_value (outf, attr, XEXP (value, 1));
      fprintf (outf, " : ");
      write_attr_value (outf, attr, XEXP (value, 2));
      fprintf (outf, ")");
      break;

    default:
      gcc_unreachable ();
    }
}

static void
write_upcase (FILE *outf, const char *str)
{
  while (*str)
    {
      /* The argument of TOUPPER should not have side effects.  */
      fputc (TOUPPER (*str), outf);
      str++;
    }
}

static void
write_indent (FILE *outf, int indent)
{
  for (; indent > 8; indent -= 8)
    fprintf (outf, "\t");

  for (; indent; indent--)
    fprintf (outf, " ");
}

/* If the target does not have annul-true or annul-false delay slots, this
   function will create a dummy eligible_for function on OUTF which always
   returns false.  KIND will be annul_true or annul_false.  */

static void
write_dummy_eligible_delay (FILE *outf, const char *kind)
{
  /* Write function prelude.  */

  fprintf (outf, "int\n");
  fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
		 "    int slot ATTRIBUTE_UNUSED,\n"
		 "    rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
		 "    int flags ATTRIBUTE_UNUSED)\n",
	   kind);
  fprintf (outf, "{\n");
  fprintf (outf, "  return 0;\n");
  fprintf (outf, "}\n\n");
}

/* Write a subroutine that is given an insn that requires a delay slot, a
   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'
   handles normal delay slots, `eligible_for_annul_true' indicates that
   the specified insn can be annulled if the branch is true, and likewise
   for `eligible_for_annul_false'.

   KIND is a string distinguishing these three cases ("delay", "annul_true",
   or "annul_false").  */

static void
write_eligible_delay (FILE *outf, const char *kind)
{
  class delay_desc *delay;
  int max_slots;
  char str[50];
  const char *pstr;
  class attr_desc *attr;
  struct attr_value *av, *common_av;
  int i;

  /* Compute the maximum number of delay slots required.  We use the delay
     ordinal times this number plus one, plus the slot number as an index into
     the appropriate predicate to test.  */

  for (delay = delays, max_slots = 0; delay; delay = delay->next)
    if (XVECLEN (delay->def, 1) / 3 > max_slots)
      max_slots = XVECLEN (delay->def, 1) / 3;

  /* Write function prelude.  */

  fprintf (outf, "int\n");
  fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
		 "		   rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
	   kind);
  fprintf (outf, "{\n");
  fprintf (outf, "  rtx_insn *insn ATTRIBUTE_UNUSED;\n");
  fprintf (outf, "\n");
  fprintf (outf, "  if (num_delay_slots (delay_insn) == 0)\n");
  fprintf (outf, "    return 0;");
  fprintf (outf, "\n");
  fprintf (outf, "  gcc_assert (slot < %d);\n", max_slots);
  fprintf (outf, "\n");
  /* Allow dbr_schedule to pass labels, etc.  This can happen if try_split
     converts a compound instruction into a loop.  */
  fprintf (outf, "  if (!INSN_P (candidate_insn))\n");
  fprintf (outf, "    return 0;\n");
  fprintf (outf, "\n");

  /* If more than one delay type, find out which type the delay insn is.  */

  if (num_delays > 1)
    {
      attr = find_attr (&delay_type_str, 0);
      gcc_assert (attr);
      common_av = find_most_used (attr);

      fprintf (outf, "  insn = delay_insn;\n");
      fprintf (outf, "  switch (recog_memoized (insn))\n");
      fprintf (outf, "    {\n");

      sprintf (str, " * %d;\n      break;", max_slots);
      for (av = attr->first_value; av; av = av->next)
	if (av != common_av)
	  write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);

      write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
      fprintf (outf, "    }\n\n");

      /* Ensure matched.  Otherwise, shouldn't have been called.  */
      fprintf (outf, "  gcc_assert (slot >= %d);\n\n", max_slots);
    }

  /* If just one type of delay slot, write simple switch.  */
  if (num_delays == 1 && max_slots == 1)
    {
      fprintf (outf, "  insn = candidate_insn;\n");
      fprintf (outf, "  switch (recog_memoized (insn))\n");
      fprintf (outf, "    {\n");

      attr = find_attr (&delay_1_0_str, 0);
      gcc_assert (attr);
      common_av = find_most_used (attr);

      for (av = attr->first_value; av; av = av->next)
	if (av != common_av)
	  write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);

      write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
      fprintf (outf, "    }\n");
    }

  else
    {
      /* Write a nested CASE.  The first indicates which condition we need to
	 test, and the inner CASE tests the condition.  */
      fprintf (outf, "  insn = candidate_insn;\n");
      fprintf (outf, "  switch (slot)\n");
      fprintf (outf, "    {\n");

      for (delay = delays; delay; delay = delay->next)
	for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
	  {
	    fprintf (outf, "    case %d:\n",
		     (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
	    fprintf (outf, "      switch (recog_memoized (insn))\n");
	    fprintf (outf, "\t{\n");

	    sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
	    pstr = str;
	    attr = find_attr (&pstr, 0);
	    gcc_assert (attr);
	    common_av = find_most_used (attr);

	    for (av = attr->first_value; av; av = av->next)
	      if (av != common_av)
		write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);

	    write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
	    fprintf (outf, "      }\n");
	  }

      fprintf (outf, "    default:\n");
      fprintf (outf, "      gcc_unreachable ();\n");
      fprintf (outf, "    }\n");
    }

  fprintf (outf, "}\n\n");
}

/* This page contains miscellaneous utility routines.  */

/* 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.  */

static char *
next_comma_elt (const char **pstr)
{
  const char *start;

  start = scan_comma_elt (pstr);

  if (start == NULL)
    return NULL;

  return attr_string (start, *pstr - start);
}

/* Return a `class attr_desc' pointer for a given named attribute.  If CREATE
   is nonzero, build a new attribute, if one does not exist.  *NAME_P is
   replaced by a pointer to a canonical copy of the string.  */

static class attr_desc *
find_attr (const char **name_p, int create)
{
  class attr_desc *attr;
  int index;
  const char *name = *name_p;

  /* Before we resort to using `strcmp', see if the string address matches
     anywhere.  In most cases, it should have been canonicalized to do so.  */
  if (name == alternative_name)
    return NULL;

  index = name[0] & (MAX_ATTRS_INDEX - 1);
  for (attr = attrs[index]; attr; attr = attr->next)
    if (name == attr->name)
      return attr;

  /* Otherwise, do it the slow way.  */
  for (attr = attrs[index]; attr; attr = attr->next)
    if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
      {
	*name_p = attr->name;
	return attr;
      }

  if (! create)
    return NULL;

  attr = oballoc (class attr_desc);
  attr->name = DEF_ATTR_STRING (name);
  attr->enum_name = 0;
  attr->first_value = attr->default_val = NULL;
  attr->is_numeric = attr->is_const = attr->is_special = 0;
  attr->next = attrs[index];
  attrs[index] = attr;

  *name_p = attr->name;

  return attr;
}

/* Create internal attribute with the given default value.  */

static void
make_internal_attr (const char *name, rtx value, int special)
{
  class attr_desc *attr;

  attr = find_attr (&name, 1);
  gcc_assert (!attr->default_val);

  attr->is_numeric = 1;
  attr->is_const = 0;
  attr->is_special = (special & ATTR_SPECIAL) != 0;
  attr->default_val = get_attr_value (file_location ("<internal>", 0, 0),
				      value, attr, -2);
}

/* Find the most used value of an attribute.  */

static struct attr_value *
find_most_used (class attr_desc *attr)
{
  struct attr_value *av;
  struct attr_value *most_used;
  int nuses;

  most_used = NULL;
  nuses = -1;

  for (av = attr->first_value; av; av = av->next)
    if (av->num_insns > nuses)
      nuses = av->num_insns, most_used = av;

  return most_used;
}

/* Return (attr_value "n") */

static rtx
make_numeric_value (int n)
{
  static rtx int_values[20];
  rtx exp;
  char *p;

  gcc_assert (n >= 0);

  if (n < 20 && int_values[n])
    return int_values[n];

  p = attr_printf (MAX_DIGITS, "%d", n);
  exp = attr_rtx (CONST_STRING, p);

  if (n < 20)
    int_values[n] = exp;

  return exp;
}

static rtx
copy_rtx_unchanging (rtx orig)
{
  if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
    return orig;

  ATTR_CURR_SIMPLIFIED_P (orig) = 1;
  return orig;
}

/* 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.  */

static void
write_const_num_delay_slots (FILE *outf)
{
  class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
  struct attr_value *av;

  if (attr)
    {
      fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
      fprintf (outf, "{\n");
      fprintf (outf, "  switch (recog_memoized (insn))\n");
      fprintf (outf, "    {\n");

      for (av = attr->first_value; av; av = av->next)
	{
	  length_used = 0;
	  walk_attr_value (av->value);
	  if (length_used)
	    write_insn_cases (outf, av->first_insn, 4);
	}

      fprintf (outf, "    default:\n");
      fprintf (outf, "      return 1;\n");
      fprintf (outf, "    }\n}\n\n");
    }
}

/* 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 (md_rtx_info *info)
{
  struct insn_reserv *decl = oballoc (struct insn_reserv);
  rtx def = info->def;

  class attr_desc attr = { };

  attr.name = DEF_ATTR_STRING (XSTR (def, 0));
  attr.loc = info->loc;

  decl->name            = DEF_ATTR_STRING (XSTR (def, 0));
  decl->default_latency = XINT (def, 1);
  decl->condexp         = check_attr_test (info->loc, XEXP (def, 2), &attr);
  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 *pattern;
};

static struct bypass_list *all_bypasses;
static size_t n_bypasses;
static size_t n_bypassed;

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->pattern)
      return;  /* already got that one */

  b = oballoc (struct bypass_list);
  b->pattern = s;
  b->next = all_bypasses;
  all_bypasses = b;
  n_bypasses++;
}

static void
gen_bypass (md_rtx_info *info)
{
  const char *p, *base;

  rtx def = info->def;
  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;

  n_bypassed = 0;

  /* 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 (fnmatch (b->pattern, r->name, 0) == 0)
        {
          n_bypassed++;
          r->bypassed = true;
          break;
        }
}

/* Check that attribute NAME is used in define_insn_reservation condition
   EXP.  Return true if it is.  */
static bool
check_tune_attr (const char *name, rtx exp)
{
  switch (GET_CODE (exp))
    {
    case AND:
      if (check_tune_attr (name, XEXP (exp, 0)))
	return true;
      return check_tune_attr (name, XEXP (exp, 1));

    case IOR:
      return (check_tune_attr (name, XEXP (exp, 0))
	      && check_tune_attr (name, XEXP (exp, 1)));

    case EQ_ATTR:
      return XSTR (exp, 0) == name;

    default:
      return false;
    }
}

/* Try to find a const attribute (usually cpu or tune) that is used
   in all define_insn_reservation conditions.  */
static class attr_desc *
find_tune_attr (rtx exp)
{
  class attr_desc *attr;

  switch (GET_CODE (exp))
    {
    case AND:
    case IOR:
      attr = find_tune_attr (XEXP (exp, 0));
      if (attr)
	return attr;
      return find_tune_attr (XEXP (exp, 1));

    case EQ_ATTR:
      if (XSTR (exp, 0) == alternative_name)
	return NULL;

      attr = find_attr (&XSTR (exp, 0), 0);
      gcc_assert (attr);

      if (attr->is_const && !attr->is_special)
	{
	  struct insn_reserv *decl;

	  for (decl = all_insn_reservs; decl; decl = decl->next)
	    if (! check_tune_attr (attr->name, decl->condexp))
	      return NULL;
	  return attr;
	}
      return NULL;

    default:
      return NULL;
    }
}

/* Create all of the attributes that describe automaton properties.
   Write the DFA and latency function prototypes to  the files that
   need to have them, and write the init_sched_attrs().  */

static void
make_automaton_attrs (void)
{
  int i;
  struct insn_reserv *decl;
  rtx code_exp, lats_exp, byps_exp;
  class attr_desc *tune_attr;

  if (n_insn_reservs == 0)
    return;

  tune_attr = find_tune_attr (all_insn_reservs->condexp);
  if (tune_attr != NULL)
    {
      rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
      struct attr_value *val;
      bool first = true;

      gcc_assert (tune_attr->is_const
		  && !tune_attr->is_special
		  && !tune_attr->is_numeric);

      /* Write the prototypes for all DFA functions.  */
      for (val = tune_attr->first_value; val; val = val->next)
	{
	  if (val == tune_attr->default_val)
	    continue;
	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
	  fprintf (dfa_file,
		   "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
		   XSTR (val->value, 0));
	}
      fprintf (dfa_file, "\n");

      /* Write the prototypes for all latency functions.  */
      for (val = tune_attr->first_value; val; val = val->next)
	{
	  if (val == tune_attr->default_val)
	    continue;
	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
	  fprintf (latency_file,
		   "extern int insn_default_latency_%s (rtx_insn *);\n",
		   XSTR (val->value, 0));
	}
      fprintf (latency_file, "\n");

      /* Write the prototypes for all automaton functions.  */
      for (val = tune_attr->first_value; val; val = val->next)
	{
	  if (val == tune_attr->default_val)
	    continue;
	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
	  fprintf (attr_file,
		   "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
		   "extern int insn_default_latency_%s (rtx_insn *);\n",
		   XSTR (val->value, 0), XSTR (val->value, 0));
	}
      fprintf (attr_file, "\n");
      fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
      fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
      fprintf (attr_file, "\n");
      fprintf (attr_file, "void\n");
      fprintf (attr_file, "init_sched_attrs (void)\n");
      fprintf (attr_file, "{\n");

      for (val = tune_attr->first_value; val; val = val->next)
	{
	  int j;
	  char *name;
	  rtx test = attr_eq (tune_attr->name, XSTR (val->value, 0));

	  if (val == tune_attr->default_val)
	    continue;
	  for (decl = all_insn_reservs, i = 0;
	       decl;
	       decl = decl->next)
	    {
	      rtx ctest = test;
	      rtx condexp
		= simplify_and_tree (decl->condexp, &ctest, -2, 0);
	      if (condexp == false_rtx)
		continue;
	      if (condexp == true_rtx)
		break;
	      condexps[i] = condexp;
	      condexps[i + 1] = make_numeric_value (decl->insn_num);
	      condexps[i + 2] = make_numeric_value (decl->default_latency);
	      i += 3;
	    }

	  code_exp = rtx_alloc (COND);
	  lats_exp = rtx_alloc (COND);

	  j = i / 3 * 2;
	  XVEC (code_exp, 0) = rtvec_alloc (j);
	  XVEC (lats_exp, 0) = rtvec_alloc (j);

	  if (decl)
	    {
	      XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
	      XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
	    }
	  else
	    {
	      XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
	      XEXP (lats_exp, 1) = make_numeric_value (0);
	    }

	  while (i > 0)
	    {
	      i -= 3;
	      j -= 2;
	      XVECEXP (code_exp, 0, j) = condexps[i];
	      XVECEXP (lats_exp, 0, j) = condexps[i];

	      XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
	      XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
	    }

	  name = XNEWVEC (char,
			  sizeof ("*internal_dfa_insn_code_")
			  + strlen (XSTR (val->value, 0)));
	  strcpy (name, "*internal_dfa_insn_code_");
	  strcat (name, XSTR (val->value, 0));
	  make_internal_attr (name, code_exp, ATTR_NONE);
	  strcpy (name, "*insn_default_latency_");
	  strcat (name, XSTR (val->value, 0));
	  make_internal_attr (name, lats_exp, ATTR_NONE);
	  XDELETEVEC (name);

	  if (first)
	    {
	      fprintf (attr_file, "  if (");
	      first = false;
	    }
	  else
	    fprintf (attr_file, "  else if (");
	  write_test_expr (attr_file, test, 0, 0);
	  fprintf (attr_file, ")\n");
	  fprintf (attr_file, "    {\n");
	  fprintf (attr_file, "      internal_dfa_insn_code\n");
	  fprintf (attr_file, "        = internal_dfa_insn_code_%s;\n",
		   XSTR (val->value, 0));
	  fprintf (attr_file, "      insn_default_latency\n");
	  fprintf (attr_file, "        = insn_default_latency_%s;\n",
		   XSTR (val->value, 0));
	  fprintf (attr_file, "    }\n");
	}

      fprintf (attr_file, "  else\n");
      fprintf (attr_file, "    gcc_unreachable ();\n");
      fprintf (attr_file, "}\n");
      fprintf (attr_file, "\n");

      XDELETEVEC (condexps);
    }
  else
    {
      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);
	}
      make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
      make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
    }

  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_bypassed * 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 ("*bypass_p", byps_exp, ATTR_NONE);
}

static void
write_header (FILE *outf)
{
  fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
	         "   from the machine description file `md'.  */\n\n");

  fprintf (outf, "#define IN_TARGET_CODE 1\n");
  fprintf (outf, "#include \"config.h\"\n");
  fprintf (outf, "#include \"system.h\"\n");
  fprintf (outf, "#include \"coretypes.h\"\n");
  fprintf (outf, "#include \"backend.h\"\n");
  fprintf (outf, "#include \"predict.h\"\n");
  fprintf (outf, "#include \"tree.h\"\n");
  fprintf (outf, "#include \"rtl.h\"\n");
  fprintf (outf, "#include \"alias.h\"\n");
  fprintf (outf, "#include \"options.h\"\n");
  fprintf (outf, "#include \"varasm.h\"\n");
  fprintf (outf, "#include \"stor-layout.h\"\n");
  fprintf (outf, "#include \"calls.h\"\n");
  fprintf (outf, "#include \"insn-attr.h\"\n");
  fprintf (outf, "#include \"memmodel.h\"\n");
  fprintf (outf, "#include \"tm_p.h\"\n");
  fprintf (outf, "#include \"insn-config.h\"\n");
  fprintf (outf, "#include \"recog.h\"\n");
  fprintf (outf, "#include \"regs.h\"\n");
  fprintf (outf, "#include \"real.h\"\n");
  fprintf (outf, "#include \"output.h\"\n");
  fprintf (outf, "#include \"toplev.h\"\n");
  fprintf (outf, "#include \"flags.h\"\n");
  fprintf (outf, "#include \"emit-rtl.h\"\n");
  fprintf (outf, "\n");
  fprintf (outf, "#define operands recog_data.operand\n\n");
}

static FILE *
open_outfile (const char *file_name)
{
  FILE *outf;
  outf = fopen (file_name, "w");
  if (! outf)
    fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
  write_header (outf);
  return outf;
}

static bool
handle_arg (const char *arg)
{
  switch (arg[1])
    {
    case 'A':
      attr_file_name = &arg[2];
      return true;
    case 'D':
      dfa_file_name = &arg[2];
      return true;
    case 'L':
      latency_file_name = &arg[2];
      return true;
    default:
      return false;
    }
}

int
main (int argc, const char **argv)
{
  class attr_desc *attr;
  class insn_def *id;
  int i;

  progname = "genattrtab";

  if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
    return FATAL_EXIT_CODE;

  attr_file = open_outfile (attr_file_name);
  dfa_file = open_outfile (dfa_file_name);
  latency_file = open_outfile (latency_file_name);

  obstack_init (hash_obstack);
  obstack_init (temp_obstack);

  /* Set up true and false rtx's */
  true_rtx = rtx_alloc (CONST_INT);
  XWINT (true_rtx, 0) = 1;
  false_rtx = rtx_alloc (CONST_INT);
  XWINT (false_rtx, 0) = 0;
  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 = DEF_ATTR_STRING ("alternative");
  length_str = DEF_ATTR_STRING ("length");
  delay_type_str = DEF_ATTR_STRING ("*delay_type");
  delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
  num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");

  /* Read the machine description.  */

  md_rtx_info info;
  while (read_md_rtx (&info))
    {
      switch (GET_CODE (info.def))
	{
	case DEFINE_INSN:
	case DEFINE_PEEPHOLE:
	case DEFINE_ASM_ATTRIBUTES:
	  gen_insn (&info);
	  break;

	case DEFINE_ATTR:
	case DEFINE_ENUM_ATTR:
	  gen_attr (&info);
	  break;

	case DEFINE_DELAY:
	  gen_delay (&info);
	  break;

	case DEFINE_INSN_RESERVATION:
	  gen_insn_reserv (&info);
	  break;

	case DEFINE_BYPASS:
	  gen_bypass (&info);
	  break;

	default:
	  break;
	}
      if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
	insn_index_number++;
    }

  if (have_error)
    return FATAL_EXIT_CODE;

  /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
  if (! got_define_asm_attributes)
    {
      md_rtx_info info;
      info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
      XVEC (info.def, 0) = rtvec_alloc (0);
      info.loc = file_location ("<internal>", 0, 0);
      info.index = -1;
      gen_insn (&info);
    }

  /* Expand DEFINE_DELAY information into new attribute.  */
  expand_delays ();

  /* Make `insn_alternatives'.  */
  int num_insn_codes = get_num_insn_codes ();
  insn_alternatives = oballocvec (alternative_mask, num_insn_codes);
  for (id = defs; id; id = id->next)
    if (id->insn_code >= 0)
      insn_alternatives[id->insn_code]
	= (((alternative_mask) 1) << id->num_alternatives) - 1;

  /* Make `insn_n_alternatives'.  */
  insn_n_alternatives = oballocvec (int, num_insn_codes);
  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.  */

  check_defs ();

  for (i = 0; i < MAX_ATTRS_INDEX; i++)
    for (attr = attrs[i]; attr; attr = attr->next)
      attr->default_val->value
	= check_attr_value (attr->loc, attr->default_val->value, attr);

  if (have_error)
    return FATAL_EXIT_CODE;

  for (i = 0; i < MAX_ATTRS_INDEX; i++)
    for (attr = attrs[i]; attr; attr = attr->next)
      fill_attr (attr);

  /* Construct extra attributes for `length'.  */
  make_length_attrs ();

  /* Perform any possible optimizations to speed up compilation.  */
  optimize_attrs (num_insn_codes);

  /* Now write out all the `gen_attr_...' routines.  Do these before the
     special routines so that they get defined before they are used.  */

  for (i = 0; i < MAX_ATTRS_INDEX; i++)
    for (attr = attrs[i]; attr; attr = attr->next)
      {
        FILE *outf;

#define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
	  outf = dfa_file;
	else if (IS_ATTR_GROUP ("*insn_default_latency"))
	  outf = latency_file;  
	else
	  outf = attr_file;
#undef IS_ATTR_GROUP

	if (! attr->is_special && ! attr->is_const)
	  write_attr_get (outf, attr);
      }

  /* Write out delay eligibility information, if DEFINE_DELAY present.
     (The function to compute the number of delay slots will be written
     below.)  */
  write_eligible_delay (attr_file, "delay");
  if (have_annul_true)
    write_eligible_delay (attr_file, "annul_true");
  else
    write_dummy_eligible_delay (attr_file, "annul_true");
  if (have_annul_false)
    write_eligible_delay (attr_file, "annul_false");
  else
    write_dummy_eligible_delay (attr_file, "annul_false");

  /* Write out constant delay slot info.  */
  write_const_num_delay_slots (attr_file);

  write_length_unit_log (attr_file);

  if (fclose (attr_file) != 0)
    fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
  if (fclose (dfa_file) != 0)
    fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
  if (fclose (latency_file) != 0)
    fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));

  return SUCCESS_EXIT_CODE;
}

