/* Generate code from machine description to compute values of attributes.
   Copyright (C) 1991-2017 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.  */

struct insn_def
{
  struct 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.  */
  struct 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.  */

struct attr_desc
{
  char *name;			/* Name of attribute.  */
  const char *enum_name;	/* Enum name for DEFINE_ENUM_NAME.  */
  struct 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.  */

struct delay_desc
{
  rtx def;			/* DEFINE_DELAY expression.  */
  struct 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;
  struct attr_desc *attr;
  struct attr_value_list *next;
};

/* Listheads of above structures.  */

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

/* Other variables.  */

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

static uint64_t *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 struct attr_desc *find_attr (const char **, int);
static rtx mk_attr_alt             (uint64_t);
static char *next_comma_elt	   (const char **);
static rtx insert_right_side	   (enum rtx_code, rtx, rtx, int, int);
static rtx copy_boolean		   (rtx);
static int compares_alternatives_p (rtx);
static void make_internal_attr     (const char *, rtx, int);
static void insert_insn_ent        (struct attr_value *, struct insn_ent *);
static void walk_attr_value	   (rtx);
static int max_attr_value	   (rtx, int*);
static int min_attr_value	   (rtx, int*);
static int or_attr_value	   (rtx, int*);
static rtx simplify_test_exp	   (rtx, int, int);
static rtx simplify_test_exp_in_temp (rtx, int, int);
static rtx copy_rtx_unchanging	   (rtx);
static bool attr_alt_subset_p      (rtx, rtx);
static bool attr_alt_subset_of_compl_p (rtx, rtx);
static void clear_struct_flag      (rtx);
static void write_attr_valueq	   (FILE *, struct attr_desc *, const char *);
static struct attr_value *find_most_used  (struct attr_desc *);
static void write_attr_set	   (FILE *, struct attr_desc *, int, rtx,
				    const char *, const char *, rtx,
				    int, int, unsigned int);
static void write_attr_case	   (FILE *, struct attr_desc *,
				    struct attr_value *,
				    int, const char *, const char *, int, rtx);
static void write_attr_value	   (FILE *, struct 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] == 'i'
	   && GET_RTX_FORMAT (code)[1] == 'i')
    {
      int  arg0 = va_arg (p, int);
      int  arg1 = va_arg (p, 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
	    && XINT (h->u.rtl, 0) == arg0
	    && XINT (h->u.rtl, 1) == arg1)
	  return h->u.rtl;

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XINT (rt_val, 0) = arg0;
	  XINT (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:
	      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 (((uint64_t) 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 |= ((uint64_t) 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, struct 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:
      {
	struct 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, struct 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, struct 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)
{
  struct insn_def *id;
  struct 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, struct 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, struct attr_desc *attr,
		int insn_code)
{
  struct attr_value *av;
  uint64_t 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)
{
  struct 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 (struct attr_desc *attr)
{
  struct attr_value *av;
  struct insn_ent *ie;
  struct 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;
  struct 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)
{
  int unknown;
  return make_numeric_value (max_attr_value (exp, &unknown));
}

static rtx
min_fn (rtx exp)
{
  int unknown;
  return make_numeric_value (min_attr_value (exp, &unknown));
}

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

  if (length_attr)
    {
      length_or = or_attr_value (length_attr->default_val->value, &unknown);
      for (av = length_attr->first_value; av; av = av->next)
	for (ie = av->first_insn; ie; ie = ie->next)
	  length_or |= or_attr_value (av->value, &unknown);
    }

  if (length_attr == NULL || unknown)
    length_unit_log = 0;
  else
    {
      length_or = ~length_or;
      for (length_unit_log = 0; length_or & 1; length_or >>= 1)
	length_unit_log++;
    }
  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 uint64_t
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 && XINT (exp, 1))
	return XINT (exp, 0);

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

      return 0;
    }
  else
    return 0;

  if (string[1] == 0)
    return ((uint64_t) 1) << (string[0] - '0');
  return ((uint64_t) 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 (uint64_t 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, struct 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 ((XINT (s1, 1) << 1) | XINT (s2, 1))
    {
    case (0 << 1) | 0:
      return !(XINT (s1, 0) &~ XINT (s2, 0));

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

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

    case (1 << 1) | 1:
      return !(XINT (s2, 0) &~ XINT (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 ((XINT (s1, 1) << 1) | XINT (s2, 1))
    {
    case (0 << 1) | 0:
      return !(XINT (s1, 0) & XINT (s2, 0));

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

    case (1 << 1) | 0:
      return !(XINT (s2, 0) &~ XINT (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)
{
  int result;

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

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

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

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

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

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

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

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

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

static rtx
mk_attr_alt (uint64_t e)
{
  return attr_rtx (EQ_ATTR_ALT, (int)e, 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;
  struct attr_desc *attr;
  struct attr_value *av;
  struct insn_ent *ie;
  struct attr_value_list *iv;
  uint64_t 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
		    && XINT (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
		     && XINT (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
		       && !XINT (left, 1))
		   || (GET_CODE (left) == EQ_ATTR
		       && XSTR (left, 0) == alternative_name)
		   || GET_CODE (right) == IOR
		   || (GET_CODE (right) == EQ_ATTR_ALT
		       && !XINT (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 (!XINT (exp, 0))
	return XINT (exp, 1) ? true_rtx : false_rtx;
      break;

    case EQ_ATTR:
      if (XSTR (exp, 0) == alternative_name)
	{
	  newexp = mk_attr_alt (((uint64_t) 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, struct attr_desc *attr)
{
  const char *fmt;
  int i, ie, j, je;

  if (GET_CODE (p) == EQ_ATTR)
    {
      if (XSTR (p, 0) != attr->name)
	return 0;
      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 (struct attr_desc ***ret)
{
  int i, j;
  int num = 0;
  struct attr_desc *attr;
  struct 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 (struct attr_desc *, num);
  sorted = XNEWVEC (struct 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++)
      {
	struct 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)
{
  struct 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;
  struct 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 (struct 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;
  struct 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)
{
  struct insn_def *id;
  rtx def = info->def;

  id = oballoc (struct 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)
{
  struct 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 (struct 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;
  struct 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;
  struct 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:
	{
	  int set = XINT (exp, 0), 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 & 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",
		       XINT (exp, 1) ? "!" : "=", bit);
	    }
	  else
	    {
	      fprintf (outf, "%s((1 << which_alternative) & %#x)",
		       XINT (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, return the maximum CONST_STRING argument
   encountered.  Set *UNKNOWNP and return INT_MAX if the value is unknown.  */

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

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

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

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

    default:
      *unknownp = 1;
      current_max = INT_MAX;
      break;
    }

  return current_max;
}

/* Given an attribute value, return the minimum CONST_STRING argument
   encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */

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

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

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

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

    default:
      *unknownp = 1;
      current_min = INT_MAX;
      break;
    }

  return current_min;
}

/* Given an attribute value, return the result of ORing together all
   CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
   if the numeric value is not known.  */

static int
or_attr_value (rtx exp, int *unknownp)
{
  int current_or;
  int i;

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

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

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

    default:
      *unknownp = 1;
      current_or = -1;
      break;
    }

  return 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, struct 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];
	struct 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, struct 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, struct 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, struct 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, struct 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:
      {
	struct 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:
      write_attr_value (outf, attr, XEXP (value, 0));
      fputc (' ', outf);
      fputc (op,  outf);
      fputc (' ', outf);
      write_attr_value (outf, attr, XEXP (value, 1));
      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)
{
  struct delay_desc *delay;
  int max_slots;
  char str[50];
  const char *pstr;
  struct 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 `struct 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 struct attr_desc *
find_attr (const char **name_p, int create)
{
  struct 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 (struct 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)
{
  struct 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 (struct 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)
{
  struct 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;

  struct attr_desc attr;
  memset (&attr, 0, sizeof (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 struct attr_desc *
find_tune_attr (rtx exp)
{
  struct 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;
  struct 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, "#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)
{
  struct attr_desc *attr;
  struct 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 (uint64_t, num_insn_codes);
  for (id = defs; id; id = id->next)
    if (id->insn_code >= 0)
      insn_alternatives[id->insn_code]
	= (((uint64_t) 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;
}

