/* Generate code from machine description to compute values of attributes.
   Copyright (C) 1991-2025 Free Software Foundation, Inc.
   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

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

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This program handles insn attributes and the DEFINE_DELAY and
   DEFINE_INSN_RESERVATION definitions.

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

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

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

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

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

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

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

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

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

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

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

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

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

#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging))
#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), in_struct))
#define ATTR_PERMANENT_P(RTX) (RTX_FLAG ((RTX), return_val))

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

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

#define DEBUG 0

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

static struct obstack obstack1, obstack2;
static struct obstack *hash_obstack = &obstack1;
static struct obstack *temp_obstack = &obstack2;

/* enough space to reserve for printing out ints */
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)

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

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

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

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

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

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

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

/* Structure for each attribute.  */

class attr_desc
{
public:
  char *name;			/* Name of attribute.  */
  const char *enum_name;	/* Enum name for DEFINE_ENUM_NAME.  */
  const char *cxx_type;		/* The associated C++ type.  */
  class attr_desc *next;	/* Next attribute.  */
  struct attr_value *first_value; /* First value of this attribute.  */
  struct attr_value *default_val; /* Default value for this attribute.  */
  file_location loc;		/* Where in the .md files it occurs.  */
  unsigned is_numeric	: 1;	/* Values of this attribute are numeric.  */
  unsigned is_const	: 1;	/* Attribute value constant for each run.  */
  unsigned is_special	: 1;	/* Don't call `write_attr_set'.  */
};

/* Structure for each DEFINE_DELAY.  */

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

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

/* Listheads of above structures.  */

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

/* Other variables.  */

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

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

static int *insn_n_alternatives;

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

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

/* Used to simplify expressions.  */

static rtx true_rtx, false_rtx;

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

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

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

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

/* Forward declarations of functions used before their definitions, only.  */
static char *attr_string           (const char *, int);
static char *attr_printf           (unsigned int, const char *, ...)
  ATTRIBUTE_PRINTF_2;
static rtx make_numeric_value      (int);
static class attr_desc *find_attr (const char **, int);
static rtx mk_attr_alt             (alternative_mask);
static char *next_comma_elt	   (const char **);
static rtx insert_right_side	   (enum rtx_code, rtx, rtx, int, int);
static rtx copy_boolean		   (rtx);
static int compares_alternatives_p (rtx);
static void make_internal_attr     (const char *, rtx, int);
static void insert_insn_ent        (struct attr_value *, struct insn_ent *);
static void walk_attr_value	   (rtx);
static int max_attr_value	   (rtx);
static int min_attr_value	   (rtx);
static unsigned int attr_value_alignment (rtx);
static rtx simplify_test_exp	   (rtx, int, int);
static rtx simplify_test_exp_in_temp (rtx, int, int);
static rtx copy_rtx_unchanging	   (rtx);
static bool attr_alt_subset_p      (rtx, rtx);
static bool attr_alt_subset_of_compl_p (rtx, rtx);
static void clear_struct_flag      (rtx);
static void write_attr_valueq	   (FILE *, class attr_desc *, const char *);
static struct attr_value *find_most_used  (class attr_desc *);
static void write_attr_set	   (FILE *, class attr_desc *, int, rtx,
				    const char *, const char *, rtx,
				    int, int, unsigned int);
static void write_attr_case	   (FILE *, class attr_desc *,
				    struct attr_value *,
				    int, const char *, const char *, int, rtx);
static void write_attr_value	   (FILE *, class attr_desc *, rtx);
static void write_upcase	   (FILE *, const char *);
static void write_indent	   (FILE *, int);
static rtx identity_fn		   (rtx);
static rtx zero_fn		   (rtx);
static rtx one_fn		   (rtx);
static rtx max_fn		   (rtx);
static rtx min_fn		   (rtx);

#define oballoc(T) XOBNEW (hash_obstack, T)
#define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))

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

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

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

static FILE *attr_file, *dfa_file, *latency_file;

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

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

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

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

#define RTL_HASH_SIZE 4093
static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];

/* Here is how primitive or already-shared RTL's hash
   codes are made.  */
#define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)

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

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

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

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

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

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

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

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

   Args are as follows:

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

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

  /* For each of several cases, search the hash table for an existing entry.
     Use that entry if one is found; otherwise create a new RTL and add it
     to the table.  */

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

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

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

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

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

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

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

      arg0 = DEF_ATTR_STRING (arg0);

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

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

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

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

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

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

      if (h == 0)
	{
	  rtl_obstack = hash_obstack;
	  rt_val = rtx_alloc (code);
	  XWINT (rt_val, 0) = arg0;
	  XWINT (rt_val, 1) = arg1;
	}
    }
  else if (code == CONST_INT)
    {
      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
      if (arg0 == 0)
	return false_rtx;
      else if (arg0 == 1)
	return true_rtx;
      else
	goto nohash;
    }
  else
    {
      int i;		/* Array indices...			*/
      const char *fmt;	/* Current rtx's format...		*/
    nohash:
      rt_val = rtx_alloc (code);	/* Allocate the storage space.  */

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

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

	    case 'L':		/* A location_t?  */
	      XLOC (rt_val, i) = va_arg (p, location_t);
	      break;

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

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

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

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

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

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

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

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

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

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

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

  va_start (p, fmt);

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

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

  return DEF_ATTR_STRING (str);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

   Return the new expression, if any.  */

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

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

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

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

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

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

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

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

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

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

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

    case ATTR_FLAG:
      break;

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

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

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

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

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

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

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

  return exp;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return exp;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  return convert_set_attr_alternative (newexp, id);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

      break;

    case SYMBOL_REF:
      if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
	break;
      /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
	 This makes the COND something that won't be considered an arbitrary
	 expression by walk_attr_value.  */
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
      exp = check_attr_value (loc, exp, attr);
      break;

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

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

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

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

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

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

    default:
      break;
    }

  return exp;
}

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

  return exp;
}

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

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

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

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

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

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

  return av;
}

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

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

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

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

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

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

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

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

  make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);

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

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

      make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      return newexp;
    }

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

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

  return (*no_address_fn) (exp);
}

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

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

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

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

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

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

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

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

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

/* Utility functions called from above routine.  */

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

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

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

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

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

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

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

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

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

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

    case EQ_ATTR_ALT:
      return 1;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
	{
	  /* If this value and the value for the prev test are the same,
	     merge the tests.  */

	  tests[i - 2]
	    = insert_right_side (IOR, tests[i - 2], newtest,
				 insn_code, insn_index);

	  /* Delete this test/value.  */
	  for (j = i; j < len - 2; j++)
	    tests[j] = tests[j + 2];
	  len -= 2;
	  i -= 2;
	}

      else
	tests[i + 1] = newval;
    }

  /* If the last test in a COND has the same value
     as the default value, that test isn't needed.  */

  while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
    len -= 2;

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

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

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

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

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

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

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

  num_insn_ents--;
}

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

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

  num_insn_ents++;
}

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

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

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

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

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

      return exp;
    }

  if (GET_CODE (exp) == code)
    {
      rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
				       term, insn_code, insn_index);
      if (new_rtx != XEXP (exp, 1))
	/* Make a copy of this expression and call recursively.  */
	newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
      else
	newexp = exp;
    }
  else
    {
      /* Insert the new term.  */
      newexp = attr_rtx (code, exp, term);
    }

  return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}

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

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

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

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

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

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

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

      return 0;
    }
  else
    return 0;

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

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

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

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

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

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

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

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

      if (insn_code_values)
        {
          struct attr_value_list *iv;
          for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
            if (iv->attr == attr)
              {
                av = iv->av;
                break;
              }
        }
      else
        {
          struct insn_ent *ie;
          for (av = attr->first_value; av; av = av->next)
            for (ie = av->first_insn; ie; ie = ie->next)
              if (ie->def->insn_code == insn_code)
                goto got_av;
        }
      if (av)
        {
        got_av:
          value = av->value;
        }
    }

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

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

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

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

    case COND:
      /* We construct an IOR of all the cases for which the
	 requested attribute value is present.  Since we start with
	 FALSE, if it is not present, FALSE will be returned.

	 Each case is the AND of the NOT's of the previous conditions with the
	 current condition; in the default case the current condition is TRUE.

	 For each possible COND value, call ourselves recursively.

	 The extra TRUE and FALSE expressions will be eliminated by another
	 call to the simplification routine.  */

      orexp = false_rtx;
      andexp = true_rtx;

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

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

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

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

    default:
      gcc_unreachable ();
    }

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

  address_used = 0;
  walk_attr_value (newexp);

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (exp == *pterm)
    return true_rtx;

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

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

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

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

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

      return exp;
    }

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

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

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

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

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

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

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

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

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

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

  return exp;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return exp;
}

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

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

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

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

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

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

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

    default:
      gcc_unreachable ();
    }
}

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

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

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

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

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

    default:
      gcc_unreachable ();
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      /* Look at the value for this insn code in the specified attribute.
	 We normally can replace this comparison with the condition that
	 would give this insn the values being tested for.  */
      if (insn_code >= 0
	  && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
	{
	  rtx x;

	  av = NULL;
	  if (insn_code_values)
	    {
	      for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
		if (iv->attr == attr)
		  {
		    av = iv->av;
		    break;
		  }
	    }
	  else
	    {
	      for (av = attr->first_value; av; av = av->next)
		for (ie = av->first_insn; ie; ie = ie->next)
		  if (ie->def->insn_code == insn_code)
		    goto got_av;
	    }

	  if (av)
	    {
	    got_av:
	      x = evaluate_eq_attr (exp, attr, av->value,
				    insn_code, insn_index);
	      x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
	      if (attr_rtx_cost (x) < 7)
		return x;
	    }
	}
      break;

    default:
      break;
    }

  /* We have already simplified this expression.  Simplifying it again
     won't buy anything unless we weren't given a valid insn code
     to process (i.e., we are canonicalizing something.).  */
  if (insn_code != -2
      && ! ATTR_IND_SIMPLIFIED_P (newexp))
    return copy_rtx_unchanging (newexp);

  return newexp;
}

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

static int
tests_attr_p (rtx p, class attr_desc *attr)
{
  const char *fmt;
  int i, ie, j, je;

  if (GET_CODE (p) == EQ_ATTR)
    {
      if (XSTR (p, 0) != attr->name)
	return 0;
      return 1;
    }

  fmt = GET_RTX_FORMAT (GET_CODE (p));
  ie = GET_RTX_LENGTH (GET_CODE (p));
  for (i = 0; i < ie; i++)
    {
      switch (*fmt++)
	{
	case 'e':
	  if (tests_attr_p (XEXP (p, i), attr))
	    return 1;
	  break;

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

  return 0;
}

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

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

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

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

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

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

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

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

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

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

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

  if (num_insn_ents == 0)
    return;

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

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

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

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

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

  /* Process one insn code at a time.  */
  for (i = -2; i < num_insn_codes; i++)
    {
      /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
	 We use it to mean "already simplified for this insn".  */
      for (iv = insn_code_values[i]; iv; iv = iv->next)
	clear_struct_flag (iv->av->value);

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

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

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

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

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

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

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

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

  code = GET_CODE (x);

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

    default:
      break;
    }

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

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

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

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

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

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

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

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

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

  if (GET_CODE (def) == DEFINE_ENUM_ATTR)
    {
      attr->enum_name = XSTR (def, 1);
      attr->cxx_type = attr->enum_name;
      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;
      attr->cxx_type = "int";
    }
  else
    {
      attr->cxx_type = concat ("attr_", attr->name, nullptr);
      name_ptr = XSTR (def, 1);
      while ((p = next_comma_elt (&name_ptr)) != NULL)
	add_attr_value (attr, p);
    }

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

  if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
    return 1;

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

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

  return 0;
}

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

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

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

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

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

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

    default:
      gcc_unreachable ();
    }
}

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

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

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

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

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

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

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

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

  if (exp == NULL)
    return;

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

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

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

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

    default:
      return;
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return attrs_cached;
}

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

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

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

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

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

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

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

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

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

    default:
      current_max = INT_MAX;
      break;
    }

  return current_max;
}

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

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

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

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

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

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

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

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

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

    default:
      current_min = INT_MAX;
      break;
    }

  return current_min;
}

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

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

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

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

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

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

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

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

    default:
      current_or = 1;
      break;
    }

  return current_or & -current_or;
}

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

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

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

  if (exp == NULL)
    return;

  code = GET_CODE (exp);
  switch (code)
    {
    case SYMBOL_REF:
      if (! ATTR_IND_SIMPLIFIED_P (exp))
	/* Since this is an arbitrary expression, it can look at anything.
	   However, constant expressions do not depend on any particular
	   insn.  */
	must_extract = must_constrain = 1;
      return;

    case MATCH_OPERAND:
      must_extract = 1;
      return;

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

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

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

    case PC:
      address_used = 1;
      return;

    case ATTR_FLAG:
      return;

    default:
      break;
    }

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

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

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

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

  /* Find the most used attribute value.  Handle that as the `default' of the
     switch we will generate.  */
  common_av = find_most_used (attr);

  /* Write out start of function, then all values with explicit `case' lines,
     then a `default', then the value with the most uses.  */
  fprintf (outf, "%s\n", attr->cxx_type);

  /* If the attribute name starts with a star, the remainder is the name of
     the subroutine to use, instead of `get_attr_...'.  */
  if (attr->name[0] == '*')
    fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
  else if (attr->is_const == 0)
    fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
  else
    {
      fprintf (outf, "get_attr_%s (void)\n", attr->name);
      fprintf (outf, "{\n");

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

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

  fprintf (outf, "{\n");

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

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

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

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

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

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

  known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);

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

  return exp;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Utilities to write in various forms.  */

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

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

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

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

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

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

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

    case ATTR:
      {
	class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
	fprintf (outf, "(%s) get_attr_%s (%s)", attr->cxx_type, attr2->name,
		 (attr2->is_const ? "" : "insn"));
      }
      break;

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

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

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

    default:
      gcc_unreachable ();
    }
}

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

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

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

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

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

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

/* Write a subroutine that is given an insn that requires a delay slot, a
   delay slot ordinal, and a candidate insn.  It returns nonzero if the
   candidate can be placed in the specified delay slot of the insn.

   We can write as many as three subroutines.  `eligible_for_delay'
   handles normal delay slots, `eligible_for_annul_true' indicates that
   the specified insn can be annulled if the branch is true, and likewise
   for `eligible_for_annul_false'.

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

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

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

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

  /* Write function prelude.  */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* This page contains miscellaneous utility routines.  */

/* Given a pointer to a (char *), return a malloc'ed string containing the
   next comma-separated element.  Advance the pointer to after the string
   scanned, or the end-of-string.  Return NULL if at end of string.  */

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

  start = scan_comma_elt (pstr);

  if (start == NULL)
    return NULL;

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

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

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

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

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

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

  if (! create)
    return NULL;

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

  *name_p = attr->name;

  return attr;
}

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

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

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

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

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

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

  most_used = NULL;
  nuses = -1;

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

  return most_used;
}

/* Return (attr_value "n") */

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

  gcc_assert (n >= 0);

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

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

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

  return exp;
}

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

  ATTR_CURR_SIMPLIFIED_P (orig) = 1;
  return orig;
}

/* Determine if an insn has a constant number of delay slots, i.e., the
   number of delay slots is not a function of the length of the insn.  */

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

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

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

      fprintf (outf, "    default:\n");
      fprintf (outf, "      return 1;\n");
      fprintf (outf, "    }\n}\n\n");
    }
}

/* Synthetic attributes used by insn-automata.cc and the scheduler.
   These are primarily concerned with (define_insn_reservation)
   patterns.  */

struct insn_reserv
{
  struct insn_reserv *next;

  const char *name;
  int default_latency;
  rtx condexp;

  /* Sequence number of this insn.  */
  int insn_num;

  /* Whether a (define_bypass) construct names this insn in its
     output list.  */
  bool bypassed;
};

static struct insn_reserv *all_insn_reservs = 0;
static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
static size_t n_insn_reservs;

/* Store information from a DEFINE_INSN_RESERVATION for future
   attribute generation.  */
static void
gen_insn_reserv (md_rtx_info *info)
{
  struct insn_reserv *decl = oballoc (struct insn_reserv);
  rtx def = info->def;

  class attr_desc attr = { };

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

  decl->name            = DEF_ATTR_STRING (XSTR (def, 0));
  decl->default_latency = XINT (def, 1);
  decl->condexp         = check_attr_test (info->loc, XEXP (def, 2), &attr);
  decl->insn_num        = n_insn_reservs;
  decl->bypassed	= false;
  decl->next            = 0;

  *last_insn_reserv_p = decl;
  last_insn_reserv_p  = &decl->next;
  n_insn_reservs++;
}

/* Store information from a DEFINE_BYPASS for future attribute
   generation.  The only thing we care about is the list of output
   insns, which will later be used to tag reservation structures with
   a 'bypassed' bit.  */

struct bypass_list
{
  struct bypass_list *next;
  const char *pattern;
};

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

static void
gen_bypass_1 (const char *s, size_t len)
{
  struct bypass_list *b;

  if (len == 0)
    return;

  s = attr_string (s, len);
  for (b = all_bypasses; b; b = b->next)
    if (s == b->pattern)
      return;  /* already got that one */

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

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

  rtx def = info->def;
  for (p = base = XSTR (def, 1); *p; p++)
    if (*p == ',')
      {
	gen_bypass_1 (base, p - base);
	do
	  p++;
	while (ISSPACE (*p));
	base = p;
      }
  gen_bypass_1 (base, p - base);
}

/* Find and mark all of the bypassed insns.  */
static void
process_bypasses (void)
{
  struct bypass_list *b;
  struct insn_reserv *r;

  n_bypassed = 0;

  /* The reservation list is likely to be much longer than the bypass
     list.  */
  for (r = all_insn_reservs; r; r = r->next)
    for (b = all_bypasses; b; b = b->next)
      if (fnmatch (b->pattern, r->name, 0) == 0)
        {
          n_bypassed++;
          r->bypassed = true;
          break;
        }
}

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

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

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

    default:
      return false;
    }
}

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

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

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

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

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

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

    default:
      return NULL;
    }
}

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

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

  if (n_insn_reservs == 0)
    return;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      XDELETEVEC (condexps);
    }
  else
    {
      code_exp = rtx_alloc (COND);
      lats_exp = rtx_alloc (COND);

      XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
      XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);

      XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
      XEXP (lats_exp, 1) = make_numeric_value (0);

      for (decl = all_insn_reservs, i = 0;
	   decl;
	   decl = decl->next, i += 2)
	{
	  XVECEXP (code_exp, 0, i)   = decl->condexp;
	  XVECEXP (lats_exp, 0, i)   = decl->condexp;

	  XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
	  XVECEXP (lats_exp, 0, i+1)
	    = make_numeric_value (decl->default_latency);
	}
      make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
      make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
    }

  if (n_bypasses == 0)
    byps_exp = make_numeric_value (0);
  else
    {
      process_bypasses ();

      byps_exp = rtx_alloc (COND);
      XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
      XEXP (byps_exp, 1) = make_numeric_value (0);
      for (decl = all_insn_reservs, i = 0;
	   decl;
	   decl = decl->next)
	if (decl->bypassed)
	  {
	    XVECEXP (byps_exp, 0, i)   = decl->condexp;
	    XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
	    i += 2;
	  }
    }

  make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
}

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

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

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

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

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

  progname = "genattrtab";

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

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

  obstack_init (hash_obstack);
  obstack_init (temp_obstack);

  /* Set up true and false rtx's */
  true_rtx = rtx_alloc (CONST_INT);
  XWINT (true_rtx, 0) = 1;
  false_rtx = rtx_alloc (CONST_INT);
  XWINT (false_rtx, 0) = 0;
  ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
  ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;

  alternative_name = DEF_ATTR_STRING ("alternative");
  length_str = DEF_ATTR_STRING ("length");
  delay_type_str = DEF_ATTR_STRING ("*delay_type");
  delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
  num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");

  /* Read the machine description.  */

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

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

	case DEFINE_DELAY:
	  gen_delay (&info);
	  break;

	case DEFINE_INSN_RESERVATION:
	  gen_insn_reserv (&info);
	  break;

	case DEFINE_BYPASS:
	  gen_bypass (&info);
	  break;

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

  if (have_error)
    return FATAL_EXIT_CODE;

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

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

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

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

  /* Construct extra attributes for automata.  */
  make_automaton_attrs ();

  /* Prepare to write out attribute subroutines by checking everything stored
     away and building the attribute cases.  */

  check_defs ();

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

  if (have_error)
    return FATAL_EXIT_CODE;

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

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

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

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

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

	if (startswith(attr->name, "*internal_dfa_insn_code"))
	  outf = dfa_file;
	else if (startswith (attr->name, "*insn_default_latency"))
	  outf = latency_file;
	else
	  outf = attr_file;

	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;
}

