/* Support routines for the various generation passes.
   Copyright (C) 2000-2021 Free Software Foundation, Inc.

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

#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 "vec.h"

#define MAX_OPERANDS 40

static rtx operand_data[MAX_OPERANDS];
static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
static char used_operands_numbers[MAX_OPERANDS];


/* In case some macros used by files we include need it, define this here.  */
int target_flags;

int insn_elision = 1;

static struct obstack obstack;
struct obstack *rtl_obstack = &obstack;

/* Counter for named patterns and INSN_CODEs.  */
static int insn_sequence_num;

/* Counter for define_splits.  */
static int split_sequence_num;

/* Counter for define_peephole2s.  */
static int peephole2_sequence_num;

static int predicable_default;
static const char *predicable_true;
static const char *predicable_false;

static const char *subst_true = "yes";
static const char *subst_false = "no";

static htab_t condition_table;

/* We initially queue all patterns, process the define_insn,
   define_cond_exec and define_subst patterns, then return
   them one at a time.  */

class queue_elem
{
public:
  rtx data;
  file_location loc;
  class queue_elem *next;
  /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT or
     DEFINE_INSN_AND_REWRITE, SPLIT points to the generated DEFINE_SPLIT.  */
  class queue_elem *split;
};

#define MNEMONIC_ATTR_NAME "mnemonic"
#define MNEMONIC_HTAB_SIZE 1024

static class queue_elem *define_attr_queue;
static class queue_elem **define_attr_tail = &define_attr_queue;
static class queue_elem *define_pred_queue;
static class queue_elem **define_pred_tail = &define_pred_queue;
static class queue_elem *define_insn_queue;
static class queue_elem **define_insn_tail = &define_insn_queue;
static class queue_elem *define_cond_exec_queue;
static class queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
static class queue_elem *define_subst_queue;
static class queue_elem **define_subst_tail = &define_subst_queue;
static class queue_elem *other_queue;
static class queue_elem **other_tail = &other_queue;
static class queue_elem *define_subst_attr_queue;
static class queue_elem **define_subst_attr_tail = &define_subst_attr_queue;

/* Mapping from DEFINE_* rtxes to their location in the source file.  */
static hash_map <rtx, file_location> *rtx_locs;

static void remove_constraints (rtx);

static int is_predicable (class queue_elem *);
static void identify_predicable_attribute (void);
static int n_alternatives (const char *);
static void collect_insn_data (rtx, int *, int *);
static const char *alter_test_for_insn (class queue_elem *,
					class queue_elem *);
static char *shift_output_template (char *, const char *, int);
static const char *alter_output_for_insn (class queue_elem *,
					  class queue_elem *,
					  int, int);
static void process_one_cond_exec (class queue_elem *);
static void process_define_cond_exec (void);
static void init_predicate_table (void);
static void record_insn_name (int, const char *);

static bool has_subst_attribute (class queue_elem *, class queue_elem *);
static const char * alter_output_for_subst_insn (rtx, int);
static void alter_attrs_for_subst_insn (class queue_elem *, int);
static void process_substs_on_one_elem (class queue_elem *,
					class queue_elem *);
static rtx subst_dup (rtx, int, int);
static void process_define_subst (void);

static const char * duplicate_alternatives (const char *, int);
static const char * duplicate_each_alternative (const char * str, int n_dup);

typedef const char * (*constraints_handler_t) (const char *, int);
static rtx alter_constraints (rtx, int, constraints_handler_t);
static rtx adjust_operands_numbers (rtx);
static rtx replace_duplicating_operands_in_pattern (rtx);

/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
   the gensupport programs.  */

rtx
gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
		   HOST_WIDE_INT arg)
{
  rtx rt = rtx_alloc (CONST_INT);

  XWINT (rt, 0) = arg;
  return rt;
}

/* Return the rtx pattern specified by the list of rtxes in a
   define_insn or define_split.  */

rtx
add_implicit_parallel (rtvec vec)
{
  if (GET_NUM_ELEM (vec) == 1)
    return RTVEC_ELT (vec, 0);
  else
    {
      rtx pattern = rtx_alloc (PARALLEL);
      XVEC (pattern, 0) = vec;
      return pattern;
    }
}

/* Predicate handling.

   We construct from the machine description a table mapping each
   predicate to a list of the rtl codes it can possibly match.  The
   function 'maybe_both_true' uses it to deduce that there are no
   expressions that can be matches by certain pairs of tree nodes.
   Also, if a predicate can match only one code, we can hardwire that
   code into the node testing the predicate.

   Some predicates are flagged as special.  validate_pattern will not
   warn about modeless match_operand expressions if they have a
   special predicate.  Predicates that allow only constants are also
   treated as special, for this purpose.

   validate_pattern will warn about predicates that allow non-lvalues
   when they appear in destination operands.

   Calculating the set of rtx codes that can possibly be accepted by a
   predicate expression EXP requires a three-state logic: any given
   subexpression may definitively accept a code C (Y), definitively
   reject a code C (N), or may have an indeterminate effect (I).  N
   and I is N; Y or I is Y; Y and I, N or I are both I.  Here are full
   truth tables.

     a b  a&b  a|b
     Y Y   Y    Y
     N Y   N    Y
     N N   N    N
     I Y   I    Y
     I N   N    I
     I I   I    I

   We represent Y with 1, N with 0, I with 2.  If any code is left in
   an I state by the complete expression, we must assume that that
   code can be accepted.  */

#define N 0
#define Y 1
#define I 2

#define TRISTATE_AND(a,b)			\
  ((a) == I ? ((b) == N ? N : I) :		\
   (b) == I ? ((a) == N ? N : I) :		\
   (a) && (b))

#define TRISTATE_OR(a,b)			\
  ((a) == I ? ((b) == Y ? Y : I) :		\
   (b) == I ? ((a) == Y ? Y : I) :		\
   (a) || (b))

#define TRISTATE_NOT(a)				\
  ((a) == I ? I : !(a))

/* 0 means no warning about that code yet, 1 means warned.  */
static char did_you_mean_codes[NUM_RTX_CODE];

/* Recursively calculate the set of rtx codes accepted by the
   predicate expression EXP, writing the result to CODES.  LOC is
   the .md file location of the directive containing EXP.  */

void
compute_test_codes (rtx exp, file_location loc, char *codes)
{
  char op0_codes[NUM_RTX_CODE];
  char op1_codes[NUM_RTX_CODE];
  char op2_codes[NUM_RTX_CODE];
  int i;

  switch (GET_CODE (exp))
    {
    case AND:
      compute_test_codes (XEXP (exp, 0), loc, op0_codes);
      compute_test_codes (XEXP (exp, 1), loc, op1_codes);
      for (i = 0; i < NUM_RTX_CODE; i++)
	codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
      break;

    case IOR:
      compute_test_codes (XEXP (exp, 0), loc, op0_codes);
      compute_test_codes (XEXP (exp, 1), loc, op1_codes);
      for (i = 0; i < NUM_RTX_CODE; i++)
	codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
      break;
    case NOT:
      compute_test_codes (XEXP (exp, 0), loc, op0_codes);
      for (i = 0; i < NUM_RTX_CODE; i++)
	codes[i] = TRISTATE_NOT (op0_codes[i]);
      break;

    case IF_THEN_ELSE:
      /* a ? b : c  accepts the same codes as (a & b) | (!a & c).  */
      compute_test_codes (XEXP (exp, 0), loc, op0_codes);
      compute_test_codes (XEXP (exp, 1), loc, op1_codes);
      compute_test_codes (XEXP (exp, 2), loc, op2_codes);
      for (i = 0; i < NUM_RTX_CODE; i++)
	codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
				TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
					      op2_codes[i]));
      break;

    case MATCH_CODE:
      /* MATCH_CODE allows a specified list of codes.  However, if it
	 does not apply to the top level of the expression, it does not
	 constrain the set of codes for the top level.  */
      if (XSTR (exp, 1)[0] != '\0')
	{
	  memset (codes, Y, NUM_RTX_CODE);
	  break;
	}

      memset (codes, N, NUM_RTX_CODE);
      {
	const char *next_code = XSTR (exp, 0);
	const char *code;

	if (*next_code == '\0')
	  {
	    error_at (loc, "empty match_code expression");
	    break;
	  }

	while ((code = scan_comma_elt (&next_code)) != 0)
	  {
	    size_t n = next_code - code;
	    int found_it = 0;

	    for (i = 0; i < NUM_RTX_CODE; i++)
	      if (!strncmp (code, GET_RTX_NAME (i), n)
		  && GET_RTX_NAME (i)[n] == '\0')
		{
		  codes[i] = Y;
		  found_it = 1;
		  break;
		}
	    if (!found_it)
	      {
		error_at (loc, "match_code \"%.*s\" matches nothing",
			  (int) n, code);
		for (i = 0; i < NUM_RTX_CODE; i++)
		  if (!strncasecmp (code, GET_RTX_NAME (i), n)
		      && GET_RTX_NAME (i)[n] == '\0'
		      && !did_you_mean_codes[i])
		    {
		      did_you_mean_codes[i] = 1;
		      message_at (loc, "(did you mean \"%s\"?)",
				  GET_RTX_NAME (i));
		    }
	      }
	  }
      }
      break;

    case MATCH_OPERAND:
      /* MATCH_OPERAND disallows the set of codes that the named predicate
	 disallows, and is indeterminate for the codes that it does allow.  */
      {
	struct pred_data *p = lookup_predicate (XSTR (exp, 1));
	if (!p)
	  {
	    error_at (loc, "reference to unknown predicate '%s'",
		      XSTR (exp, 1));
	    break;
	  }
	for (i = 0; i < NUM_RTX_CODE; i++)
	  codes[i] = p->codes[i] ? I : N;
      }
      break;


    case MATCH_TEST:
      /* (match_test WHATEVER) is completely indeterminate.  */
      memset (codes, I, NUM_RTX_CODE);
      break;

    default:
      error_at (loc, "'%s' cannot be used in predicates or constraints",
		GET_RTX_NAME (GET_CODE (exp)));
      memset (codes, I, NUM_RTX_CODE);
      break;
    }
}

#undef TRISTATE_OR
#undef TRISTATE_AND
#undef TRISTATE_NOT

/* Return true if NAME is a valid predicate name.  */

static bool
valid_predicate_name_p (const char *name)
{
  const char *p;

  if (!ISALPHA (name[0]) && name[0] != '_')
    return false;
  for (p = name + 1; *p; p++)
    if (!ISALNUM (*p) && *p != '_')
      return false;
  return true;
}

/* Process define_predicate directive DESC, which appears at location LOC.
   Compute the set of codes that can be matched, and record this as a known
   predicate.  */

static void
process_define_predicate (rtx desc, file_location loc)
{
  struct pred_data *pred;
  char codes[NUM_RTX_CODE];
  int i;

  if (!valid_predicate_name_p (XSTR (desc, 0)))
    {
      error_at (loc, "%s: predicate name must be a valid C function name",
		XSTR (desc, 0));
      return;
    }

  pred = XCNEW (struct pred_data);
  pred->name = XSTR (desc, 0);
  pred->exp = XEXP (desc, 1);
  pred->c_block = XSTR (desc, 2);
  if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
    pred->special = true;

  compute_test_codes (XEXP (desc, 1), loc, codes);

  for (i = 0; i < NUM_RTX_CODE; i++)
    if (codes[i] != N)
      add_predicate_code (pred, (enum rtx_code) i);

  add_predicate (pred);
}
#undef I
#undef N
#undef Y

/* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
   element.  */

static class queue_elem *
queue_pattern (rtx pattern, class queue_elem ***list_tail,
	       file_location loc)
{
  class queue_elem *e = XNEW (class queue_elem);
  e->data = pattern;
  e->loc = loc;
  e->next = NULL;
  e->split = NULL;
  **list_tail = e;
  *list_tail = &e->next;
  return e;
}

/* Remove element ELEM from QUEUE.  */
static void
remove_from_queue (class queue_elem *elem, class queue_elem **queue)
{
  class queue_elem *prev, *e;
  prev = NULL;
  for (e = *queue; e ; e = e->next)
    {
      if (e == elem)
	break;
      prev = e;
    }
  if (e == NULL)
    return;

  if (prev)
    prev->next = elem->next;
  else
    *queue = elem->next;
}

/* Build a define_attr for an binary attribute with name NAME and
   possible values "yes" and "no", and queue it.  */
static void
add_define_attr (const char *name)
{
  class queue_elem *e = XNEW (class queue_elem);
  rtx t1 = rtx_alloc (DEFINE_ATTR);
  XSTR (t1, 0) = name;
  XSTR (t1, 1) = "no,yes";
  XEXP (t1, 2) = rtx_alloc (CONST_STRING);
  XSTR (XEXP (t1, 2), 0) = "yes";
  e->data = t1;
  e->loc = file_location ("built-in", -1, -1);
  e->next = define_attr_queue;
  define_attr_queue = e;

}

/* Recursively remove constraints from an rtx.  */

static void
remove_constraints (rtx part)
{
  int i, j;
  const char *format_ptr;

  if (part == 0)
    return;

  if (GET_CODE (part) == MATCH_OPERAND)
    XSTR (part, 2) = "";
  else if (GET_CODE (part) == MATCH_SCRATCH)
    XSTR (part, 1) = "";

  format_ptr = GET_RTX_FORMAT (GET_CODE (part));

  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
    switch (*format_ptr++)
      {
      case 'e':
      case 'u':
	remove_constraints (XEXP (part, i));
	break;
      case 'E':
	if (XVEC (part, i) != NULL)
	  for (j = 0; j < XVECLEN (part, i); j++)
	    remove_constraints (XVECEXP (part, i, j));
	break;
      }
}

/* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
   with MATCH_OP_DUPs in X.  */

static rtx
replace_operands_with_dups (rtx x)
{
  if (x == 0)
    return x;

  rtx newx;
  if (GET_CODE (x) == MATCH_OPERAND)
    {
      newx = rtx_alloc (MATCH_DUP);
      XINT (newx, 0) = XINT (x, 0);
      x = newx;
    }
  else if (GET_CODE (x) == MATCH_OPERATOR)
    {
      newx = rtx_alloc (MATCH_OP_DUP);
      XINT (newx, 0) = XINT (x, 0);
      XVEC (newx, 1) = XVEC (x, 2);
      x = newx;
    }
  else
    newx = shallow_copy_rtx (x);

  const char *format_ptr = GET_RTX_FORMAT (GET_CODE (x));
  for (int i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
    switch (*format_ptr++)
      {
      case 'e':
      case 'u':
	XEXP (newx, i) = replace_operands_with_dups (XEXP (x, i));
	break;
      case 'E':
	if (XVEC (x, i) != NULL)
	  {
	    XVEC (newx, i) = rtvec_alloc (XVECLEN (x, i));
	    for (int j = 0; j < XVECLEN (x, i); j++)
	      XVECEXP (newx, i, j)
		= replace_operands_with_dups (XVECEXP (x, i, j));
	  }
	break;
      }
  return newx;
}

/* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
   a sequence that should be generated by the splitter.  */

static rtvec
gen_rewrite_sequence (rtvec vec)
{
  rtvec new_vec = rtvec_alloc (1);
  rtx x = add_implicit_parallel (vec);
  RTVEC_ELT (new_vec, 0) = replace_operands_with_dups (x);
  return new_vec;
}

/* Process a top level rtx in some way, queuing as appropriate.  */

static void
process_rtx (rtx desc, file_location loc)
{
  switch (GET_CODE (desc))
    {
    case DEFINE_INSN:
      queue_pattern (desc, &define_insn_tail, loc);
      break;

    case DEFINE_COND_EXEC:
      queue_pattern (desc, &define_cond_exec_tail, loc);
      break;

    case DEFINE_SUBST:
      queue_pattern (desc, &define_subst_tail, loc);
      break;

    case DEFINE_SUBST_ATTR:
      queue_pattern (desc, &define_subst_attr_tail, loc);
      break;

    case DEFINE_ATTR:
    case DEFINE_ENUM_ATTR:
      queue_pattern (desc, &define_attr_tail, loc);
      break;

    case DEFINE_PREDICATE:
    case DEFINE_SPECIAL_PREDICATE:
      process_define_predicate (desc, loc);
      /* Fall through.  */

    case DEFINE_CONSTRAINT:
    case DEFINE_REGISTER_CONSTRAINT:
    case DEFINE_MEMORY_CONSTRAINT:
    case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
    case DEFINE_RELAXED_MEMORY_CONSTRAINT:
    case DEFINE_ADDRESS_CONSTRAINT:
      queue_pattern (desc, &define_pred_tail, loc);
      break;

    case DEFINE_INSN_AND_SPLIT:
    case DEFINE_INSN_AND_REWRITE:
      {
	const char *split_cond;
	rtx split;
	rtvec attr;
	int i;
	class queue_elem *insn_elem;
	class queue_elem *split_elem;
	int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);

	/* Create a split with values from the insn_and_split.  */
	split = rtx_alloc (DEFINE_SPLIT);

	i = XVECLEN (desc, 1);
	XVEC (split, 0) = rtvec_alloc (i);
	while (--i >= 0)
	  {
	    XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
	    remove_constraints (XVECEXP (split, 0, i));
	  }

	/* If the split condition starts with "&&", append it to the
	   insn condition to create the new split condition.  */
	split_cond = XSTR (desc, 4);
	if (split_cond[0] == '&' && split_cond[1] == '&')
	  {
	    rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
	    split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
							    split_cond + 2);
	  }
	else if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
	  error_at (loc, "the rewrite condition must start with `&&'");
	XSTR (split, 1) = split_cond;
	if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
	  XVEC (split, 2) = gen_rewrite_sequence (XVEC (desc, 1));
	else
	  XVEC (split, 2) = XVEC (desc, 5);
	XSTR (split, 3) = XSTR (desc, split_code);

	/* Fix up the DEFINE_INSN.  */
	attr = XVEC (desc, split_code + 1);
	PUT_CODE (desc, DEFINE_INSN);
	XVEC (desc, 4) = attr;

	/* Queue them.  */
	insn_elem = queue_pattern (desc, &define_insn_tail, loc);
	split_elem = queue_pattern (split, &other_tail, loc);
	insn_elem->split = split_elem;
	break;
      }

    default:
      queue_pattern (desc, &other_tail, loc);
      break;
    }
}

/* Return true if attribute PREDICABLE is true for ELEM, which holds
   a DEFINE_INSN.  */

static int
is_predicable (class queue_elem *elem)
{
  rtvec vec = XVEC (elem->data, 4);
  const char *value;
  int i;

  if (! vec)
    return predicable_default;

  for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
    {
      rtx sub = RTVEC_ELT (vec, i);
      switch (GET_CODE (sub))
	{
	case SET_ATTR:
	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
	    {
	      value = XSTR (sub, 1);
	      goto found;
	    }
	  break;

	case SET_ATTR_ALTERNATIVE:
	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
	    {
	      error_at (elem->loc, "multiple alternatives for `predicable'");
	      return 0;
	    }
	  break;

	case SET:
	  if (GET_CODE (SET_DEST (sub)) != ATTR
	      || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
	    break;
	  sub = SET_SRC (sub);
	  if (GET_CODE (sub) == CONST_STRING)
	    {
	      value = XSTR (sub, 0);
	      goto found;
	    }

	  /* ??? It would be possible to handle this if we really tried.
	     It's not easy though, and I'm not going to bother until it
	     really proves necessary.  */
	  error_at (elem->loc, "non-constant value for `predicable'");
	  return 0;

	default:
	  gcc_unreachable ();
	}
    }

  return predicable_default;

 found:
  /* Find out which value we're looking at.  Multiple alternatives means at
     least one is predicable.  */
  if (strchr (value, ',') != NULL)
    return 1;
  if (strcmp (value, predicable_true) == 0)
    return 1;
  if (strcmp (value, predicable_false) == 0)
    return 0;

  error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
  return 0;
}

/* Find attribute SUBST in ELEM and assign NEW_VALUE to it.  */
static void
change_subst_attribute (class queue_elem *elem,
			class queue_elem *subst_elem,
			const char *new_value)
{
  rtvec attrs_vec = XVEC (elem->data, 4);
  const char *subst_name = XSTR (subst_elem->data, 0);
  int i;

  if (! attrs_vec)
    return;

  for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
    {
      rtx cur_attr = RTVEC_ELT (attrs_vec, i);
      if (GET_CODE (cur_attr) != SET_ATTR)
	continue;
      if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
	{
	  XSTR (cur_attr, 1) = new_value;
	  return;
	}
    }
}

/* Return true if ELEM has the attribute with the name of DEFINE_SUBST
   represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
   DEFINE_SUBST isn't applied to patterns without such attribute.  In other
   words, we suppose the default value of the attribute to be 'no' since it is
   always generated automatically in read-rtl.c.  */
static bool
has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
{
  rtvec attrs_vec = XVEC (elem->data, 4);
  const char *value, *subst_name = XSTR (subst_elem->data, 0);
  int i;

  if (! attrs_vec)
    return false;

  for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
    {
      rtx cur_attr = RTVEC_ELT (attrs_vec, i);
      switch (GET_CODE (cur_attr))
	{
	case SET_ATTR:
	  if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
	    {
	      value = XSTR (cur_attr, 1);
	      goto found;
	    }
	  break;

	case SET:
	  if (GET_CODE (SET_DEST (cur_attr)) != ATTR
	      || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
	    break;
	  cur_attr = SET_SRC (cur_attr);
	  if (GET_CODE (cur_attr) == CONST_STRING)
	    {
	      value = XSTR (cur_attr, 0);
	      goto found;
	    }

	  /* Only (set_attr "subst" "yes/no") and
		  (set (attr "subst" (const_string "yes/no")))
	     are currently allowed.  */
	  error_at (elem->loc, "unsupported value for `%s'", subst_name);
	  return false;

	case SET_ATTR_ALTERNATIVE:
	  if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
	    error_at (elem->loc,
		      "%s: `set_attr_alternative' is unsupported by "
		      "`define_subst'", XSTR (elem->data, 0));
	  return false;


	default:
	  gcc_unreachable ();
	}
    }

  return false;

 found:
  if (strcmp (value, subst_true) == 0)
    return true;
  if (strcmp (value, subst_false) == 0)
    return false;

  error_at (elem->loc, "unknown value `%s' for `%s' attribute",
	    value, subst_name);
  return false;
}

/* Compare RTL-template of original define_insn X to input RTL-template of
   define_subst PT.  Return 1 if the templates match, 0 otherwise.
   During the comparison, the routine also fills global_array OPERAND_DATA.  */
static bool
subst_pattern_match (rtx x, rtx pt, file_location loc)
{
  RTX_CODE code, code_pt;
  int i, j, len;
  const char *fmt, *pred_name;

  code = GET_CODE (x);
  code_pt = GET_CODE (pt);

  if (code_pt == MATCH_OPERAND)
    {
      /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
	 always accept them.  */
      if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
	  && (code != MATCH_DUP && code != MATCH_OP_DUP))
	return false; /* Modes don't match.  */

      if (code == MATCH_OPERAND)
	{
	  pred_name = XSTR (pt, 1);
	  if (pred_name[0] != 0)
	    {
	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
		return false; /* Predicates don't match.  */
	    }
	}

      gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
      operand_data[XINT (pt, 0)] = x;
      return true;
    }

  if (code_pt == MATCH_OPERATOR)
    {
      int x_vecexp_pos = -1;

      /* Compare modes.  */
      if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
	return false;

      /* In case X is also match_operator, compare predicates.  */
      if (code == MATCH_OPERATOR)
	{
	  pred_name = XSTR (pt, 1);
	  if (pred_name[0] != 0)
	    {
	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
		return false;
	    }
	}

      /* Compare operands.
	 MATCH_OPERATOR in input template could match in original template
	 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
	 In the first case operands are at (XVECEXP (x, 2, j)), in the second
	 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
	 X_VECEXP_POS variable shows, where to look for these operands.  */
      if (code == UNSPEC
	  || code == UNSPEC_VOLATILE)
	x_vecexp_pos = 0;
      else if (code == MATCH_OPERATOR)
	x_vecexp_pos = 2;
      else
	x_vecexp_pos = -1;

      /* MATCH_OPERATOR or UNSPEC case.  */
      if (x_vecexp_pos >= 0)
	{
	  /* Compare operands number in X and PT.  */
	  if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
	    return false;
	  for (j = 0; j < XVECLEN (pt, 2); j++)
	    if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
				      XVECEXP (pt, 2, j), loc))
	      return false;
	}

      /* Ordinary operator.  */
      else
	{
	  /* Compare operands number in X and PT.
	     We count operands differently for X and PT since we compare
	     an operator (with operands directly in RTX) and MATCH_OPERATOR
	     (that has a vector with operands).  */
	  if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
	    return false;
	  for (j = 0; j < XVECLEN (pt, 2); j++)
	    if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
	      return false;
	}

      /* Store the operand to OPERAND_DATA array.  */
      gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
      operand_data[XINT (pt, 0)] = x;
      return true;
    }

  if (code_pt == MATCH_PAR_DUP
      || code_pt == MATCH_DUP
      || code_pt == MATCH_OP_DUP
      || code_pt == MATCH_SCRATCH
      || code_pt == MATCH_PARALLEL)
    {
      /* Currently interface for these constructions isn't defined -
	 probably they aren't needed in input template of define_subst at all.
	 So, for now their usage in define_subst is forbidden.  */
      error_at (loc, "%s cannot be used in define_subst",
		GET_RTX_NAME (code_pt));
    }

  gcc_assert (code != MATCH_PAR_DUP
      && code_pt != MATCH_DUP
      && code_pt != MATCH_OP_DUP
      && code_pt != MATCH_SCRATCH
      && code_pt != MATCH_PARALLEL
      && code_pt != MATCH_OPERAND
      && code_pt != MATCH_OPERATOR);
  /* If PT is none of the handled above, then we match only expressions with
     the same code in X.  */
  if (code != code_pt)
    return false;

  fmt = GET_RTX_FORMAT (code_pt);
  len = GET_RTX_LENGTH (code_pt);

  for (i = 0; i < len; i++)
    {
      if (fmt[i] == '0')
	break;

      switch (fmt[i])
	{
	case 'r': case 'p': case 'i': case 'w': case 's':
	  continue;

	case 'e': case 'u':
	  if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
	    return false;
	  break;
	case 'E':
	  {
	    if (XVECLEN (x, i) != XVECLEN (pt, i))
	      return false;
	    for (j = 0; j < XVECLEN (pt, i); j++)
	      if (!subst_pattern_match (XVECEXP (x, i, j),
					XVECEXP (pt, i, j), loc))
		return false;
	    break;
	  }
	default:
	  gcc_unreachable ();
	}
    }

  return true;
}

/* Examine the attribute "predicable"; discover its boolean values
   and its default.  */

static void
identify_predicable_attribute (void)
{
  class queue_elem *elem;
  char *p_true, *p_false;
  const char *value;

  /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
  for (elem = define_attr_queue; elem ; elem = elem->next)
    if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
      goto found;

  error_at (define_cond_exec_queue->loc,
	    "attribute `predicable' not defined");
  return;

 found:
  value = XSTR (elem->data, 1);
  p_false = xstrdup (value);
  p_true = strchr (p_false, ',');
  if (p_true == NULL || strchr (++p_true, ',') != NULL)
    {
      error_at (elem->loc, "attribute `predicable' is not a boolean");
      free (p_false);
      return;
    }
  p_true[-1] = '\0';

  predicable_true = p_true;
  predicable_false = p_false;

  switch (GET_CODE (XEXP (elem->data, 2)))
    {
    case CONST_STRING:
      value = XSTR (XEXP (elem->data, 2), 0);
      break;

    case CONST:
      error_at (elem->loc, "attribute `predicable' cannot be const");
      free (p_false);
      return;

    default:
      error_at (elem->loc,
		"attribute `predicable' must have a constant default");
      free (p_false);
      return;
    }

  if (strcmp (value, p_true) == 0)
    predicable_default = 1;
  else if (strcmp (value, p_false) == 0)
    predicable_default = 0;
  else
    {
      error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
		value);
      free (p_false);
    }
}

/* Return the number of alternatives in constraint S.  */

static int
n_alternatives (const char *s)
{
  int n = 1;

  if (s)
    while (*s)
      n += (*s++ == ',');

  return n;
}

/* The routine scans rtl PATTERN, find match_operand in it and counts
   number of alternatives.  If PATTERN contains several match_operands
   with different number of alternatives, error is emitted, and the
   routine returns 0.  If all match_operands in PATTERN have the same
   number of alternatives, it's stored in N_ALT, and the routine returns 1.
   LOC is the location of PATTERN, for error reporting.  */
static int
get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len;

  if (!n_alt)
    return 0;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_OPERAND:
      i = n_alternatives (XSTR (pattern, 2));
      /* n_alternatives returns 1 if constraint string is empty -
	 here we fix it up.  */
      if (!*(XSTR (pattern, 2)))
	i = 0;
      if (*n_alt <= 0)
	*n_alt = i;

      else if (i && i != *n_alt)
	{
	  error_at (loc, "wrong number of alternatives in operand %d",
		    XINT (pattern, 0));
	  return 0;
	}

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
	    return 0;
	  break;

	case 'V':
	  if (XVEC (pattern, i) == NULL)
	    break;
	  /* FALLTHRU */

	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
	      return 0;
	  break;

	case 'r': case 'p': case 'i': case 'w':
	case '0': case 's': case 'S': case 'T':
	  break;

	default:
	  gcc_unreachable ();
	}
    }
    return 1;
}

/* Determine how many alternatives there are in INSN, and how many
   operands.  */

static void
collect_insn_data (rtx pattern, int *palt, int *pmax)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_OPERAND:
    case MATCH_SCRATCH:
      i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
      *palt = (i > *palt ? i : *palt);
      /* Fall through.  */

    case MATCH_OPERATOR:
    case MATCH_PARALLEL:
      i = XINT (pattern, 0);
      if (i > *pmax)
	*pmax = i;
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  collect_insn_data (XEXP (pattern, i), palt, pmax);
	  break;

	case 'V':
	  if (XVEC (pattern, i) == NULL)
	    break;
	  /* Fall through.  */
	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
	  break;

	case 'r': case 'p': case 'i': case 'w':
	case '0': case 's': case 'S': case 'T':
	  break;

	default:
	  gcc_unreachable ();
	}
    }
}

static rtx
alter_predicate_for_insn (rtx pattern, int alt, int max_op,
			  file_location loc)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_OPERAND:
      {
	const char *c = XSTR (pattern, 2);

	if (n_alternatives (c) != 1)
	  {
	    error_at (loc, "too many alternatives for operand %d",
		      XINT (pattern, 0));
	    return NULL;
	  }

	/* Replicate C as needed to fill out ALT alternatives.  */
	if (c && *c && alt > 1)
	  {
	    size_t c_len = strlen (c);
	    size_t len = alt * (c_len + 1);
	    char *new_c = XNEWVEC (char, len);

	    memcpy (new_c, c, c_len);
	    for (i = 1; i < alt; ++i)
	      {
		new_c[i * (c_len + 1) - 1] = ',';
		memcpy (&new_c[i * (c_len + 1)], c, c_len);
	      }
	    new_c[len - 1] = '\0';
	    XSTR (pattern, 2) = new_c;
	  }
      }
      /* Fall through.  */

    case MATCH_OPERATOR:
    case MATCH_SCRATCH:
    case MATCH_PARALLEL:
      XINT (pattern, 0) += max_op;
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      rtx r;

      switch (fmt[i])
	{
	case 'e': case 'u':
	  r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
	  if (r == NULL)
	    return r;
	  break;

	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    {
	      r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
					    alt, max_op, loc);
	      if (r == NULL)
		return r;
	    }
	  break;

	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  return pattern;
}

/* Duplicate constraints in PATTERN.  If pattern is from original
   rtl-template, we need to duplicate each alternative - for that we
   need to use duplicate_each_alternative () as a functor ALTER.
   If pattern is from output-pattern of define_subst, we need to
   duplicate constraints in another way - with duplicate_alternatives ().
   N_DUP is multiplication factor.  */
static rtx
alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_OPERAND:
      XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      rtx r;

      switch (fmt[i])
	{
	case 'e': case 'u':
	  r = alter_constraints (XEXP (pattern, i), n_dup, alter);
	  if (r == NULL)
	    return r;
	  break;

	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    {
	      r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
	      if (r == NULL)
		return r;
	    }
	  break;

	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
	  break;

	default:
	  break;
	}
    }

  return pattern;
}

static const char *
alter_test_for_insn (class queue_elem *ce_elem,
		     class queue_elem *insn_elem)
{
  return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
					    XSTR (insn_elem->data, 2));
}

/* Modify VAL, which is an attribute expression for the "enabled" attribute,
   to take "ce_enabled" into account.  Return the new expression.  */
static rtx
modify_attr_enabled_ce (rtx val)
{
  rtx eq_attr, str;
  rtx ite;
  eq_attr = rtx_alloc (EQ_ATTR);
  ite = rtx_alloc (IF_THEN_ELSE);
  str = rtx_alloc (CONST_STRING);

  XSTR (eq_attr, 0) = "ce_enabled";
  XSTR (eq_attr, 1) = "yes";
  XSTR (str, 0) = "no";
  XEXP (ite, 0) = eq_attr;
  XEXP (ite, 1) = val;
  XEXP (ite, 2) = str;

  return ite;
}

/* Alter the attribute vector of INSN, which is a COND_EXEC variant created
   from a define_insn pattern.  We must modify the "predicable" attribute
   to be named "ce_enabled", and also change any "enabled" attribute that's
   present so that it takes ce_enabled into account.
   We rely on the fact that INSN was created with copy_rtx, and modify data
   in-place.  */

static void
alter_attrs_for_insn (rtx insn)
{
  static bool global_changes_made = false;
  rtvec vec = XVEC (insn, 4);
  rtvec new_vec;
  rtx val, set;
  int num_elem;
  int predicable_idx = -1;
  int enabled_idx = -1;
  int i;

  if (! vec)
    return;

  num_elem = GET_NUM_ELEM (vec);
  for (i = num_elem - 1; i >= 0; --i)
    {
      rtx sub = RTVEC_ELT (vec, i);
      switch (GET_CODE (sub))
	{
	case SET_ATTR:
	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
	    {
	      predicable_idx = i;
	      XSTR (sub, 0) = "ce_enabled";
	    }
	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
	    {
	      enabled_idx = i;
	      XSTR (sub, 0) = "nonce_enabled";
	    }
	  break;

	case SET_ATTR_ALTERNATIVE:
	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
	    /* We already give an error elsewhere.  */
	    return;
	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
	    {
	      enabled_idx = i;
	      XSTR (sub, 0) = "nonce_enabled";
	    }
	  break;

	case SET:
	  if (GET_CODE (SET_DEST (sub)) != ATTR)
	    break;
	  if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
	    {
	      sub = SET_SRC (sub);
	      if (GET_CODE (sub) == CONST_STRING)
		{
		  predicable_idx = i;
		  XSTR (sub, 0) = "ce_enabled";
		}
	      else
		/* We already give an error elsewhere.  */
		return;
	      break;
	    }
	  if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
	    {
	      enabled_idx = i;
	      XSTR (SET_DEST (sub), 0) = "nonce_enabled";
	    }
	  break;

	default:
	  gcc_unreachable ();
	}
    }
  if (predicable_idx == -1)
    return;

  if (!global_changes_made)
    {
      class queue_elem *elem;

      global_changes_made = true;
      add_define_attr ("ce_enabled");
      add_define_attr ("nonce_enabled");

      for (elem = define_attr_queue; elem ; elem = elem->next)
	if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
	  {
	    XEXP (elem->data, 2)
	      = modify_attr_enabled_ce (XEXP (elem->data, 2));
	  }
    }
  if (enabled_idx == -1)
    return;

  new_vec = rtvec_alloc (num_elem + 1);
  for (i = 0; i < num_elem; i++)
    RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
  val = rtx_alloc (IF_THEN_ELSE);
  XEXP (val, 0) = rtx_alloc (EQ_ATTR);
  XEXP (val, 1) = rtx_alloc (CONST_STRING);
  XEXP (val, 2) = rtx_alloc (CONST_STRING);
  XSTR (XEXP (val, 0), 0) = "nonce_enabled";
  XSTR (XEXP (val, 0), 1) = "yes";
  XSTR (XEXP (val, 1), 0) = "yes";
  XSTR (XEXP (val, 2), 0) = "no";
  set = rtx_alloc (SET);
  SET_DEST (set) = rtx_alloc (ATTR);
  XSTR (SET_DEST (set), 0) = "enabled";
  SET_SRC (set) = modify_attr_enabled_ce (val);
  RTVEC_ELT (new_vec, i) = set;
  XVEC (insn, 4) = new_vec;
}

/* As number of constraints is changed after define_subst, we need to
   process attributes as well - we need to duplicate them the same way
   that we duplicated constraints in original pattern
   ELEM is a queue element, containing our rtl-template,
   N_DUP - multiplication factor.  */
static void
alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
{
  rtvec vec = XVEC (elem->data, 4);
  int num_elem;
  int i;

  if (n_dup < 2 || ! vec)
    return;

  num_elem = GET_NUM_ELEM (vec);
  for (i = num_elem - 1; i >= 0; --i)
    {
      rtx sub = RTVEC_ELT (vec, i);
      switch (GET_CODE (sub))
	{
	case SET_ATTR:
	  if (strchr (XSTR (sub, 1), ',') != NULL)
	    XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
	  break;

	case SET_ATTR_ALTERNATIVE:
	case SET:
	  error_at (elem->loc,
		    "%s: `define_subst' does not support attributes "
		    "assigned by `set' and `set_attr_alternative'",
		    XSTR (elem->data, 0));
	  return;

	default:
	  gcc_unreachable ();
	}
    }
}

/* Adjust all of the operand numbers in SRC to match the shift they'll
   get from an operand displacement of DISP.  Return a pointer after the
   adjusted string.  */

static char *
shift_output_template (char *dest, const char *src, int disp)
{
  while (*src)
    {
      char c = *src++;
      *dest++ = c;
      if (c == '%')
	{
	  c = *src++;
	  if (ISDIGIT ((unsigned char) c))
	    c += disp;
	  else if (ISALPHA (c))
	    {
	      *dest++ = c;
	      c = *src++ + disp;
	    }
	  *dest++ = c;
	}
    }

  return dest;
}

static const char *
alter_output_for_insn (class queue_elem *ce_elem,
		       class queue_elem *insn_elem,
		       int alt, int max_op)
{
  const char *ce_out, *insn_out;
  char *result, *p;
  size_t len, ce_len, insn_len;

  /* ??? Could coordinate with genoutput to not duplicate code here.  */

  ce_out = XSTR (ce_elem->data, 2);
  insn_out = XTMPL (insn_elem->data, 3);
  if (!ce_out || *ce_out == '\0')
    return insn_out;

  ce_len = strlen (ce_out);
  insn_len = strlen (insn_out);

  if (*insn_out == '*')
    /* You must take care of the predicate yourself.  */
    return insn_out;

  if (*insn_out == '@')
    {
      len = (ce_len + 1) * alt + insn_len + 1;
      p = result = XNEWVEC (char, len);

      do
	{
	  do
	    *p++ = *insn_out++;
	  while (ISSPACE ((unsigned char) *insn_out));

	  if (*insn_out != '#')
	    {
	      p = shift_output_template (p, ce_out, max_op);
	      *p++ = ' ';
	    }

	  do
	    *p++ = *insn_out++;
	  while (*insn_out && *insn_out != '\n');
	}
      while (*insn_out);
      *p = '\0';
    }
  else
    {
      len = ce_len + 1 + insn_len + 1;
      result = XNEWVEC (char, len);

      p = shift_output_template (result, ce_out, max_op);
      *p++ = ' ';
      memcpy (p, insn_out, insn_len + 1);
    }

  return result;
}

/* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
   string, duplicated N_DUP times.  */

static const char *
duplicate_alternatives (const char * str, int n_dup)
{
  int i, len, new_len;
  char *result, *sp;
  const char *cp;

  if (n_dup < 2)
    return str;

  while (ISSPACE (*str))
    str++;

  if (*str == '\0')
    return str;

  cp = str;
  len = strlen (str);
  new_len = (len + 1) * n_dup;

  sp = result = XNEWVEC (char, new_len);

  /* Global modifier characters mustn't be duplicated: skip if found.  */
  if (*cp == '=' || *cp == '+' || *cp == '%')
    {
      *sp++ = *cp++;
      len--;
    }

  /* Copy original constraints N_DUP times.  */
  for (i = 0; i < n_dup; i++, sp += len+1)
    {
      memcpy (sp, cp, len);
      *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
    }

  return result;
}

/* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
   each alternative from the original string is duplicated N_DUP times.  */
static const char *
duplicate_each_alternative (const char * str, int n_dup)
{
  int i, len, new_len;
  char *result, *sp, *ep, *cp;

  if (n_dup < 2)
    return str;

  while (ISSPACE (*str))
    str++;

  if (*str == '\0')
    return str;

  cp = xstrdup (str);

  new_len = (strlen (cp) + 1) * n_dup;

  sp = result = XNEWVEC (char, new_len);

  /* Global modifier characters mustn't be duplicated: skip if found.  */
  if (*cp == '=' || *cp == '+' || *cp == '%')
      *sp++ = *cp++;

  do
    {
      if ((ep = strchr (cp, ',')) != NULL)
	*ep++ = '\0';
      len = strlen (cp);

      /* Copy a constraint N_DUP times.  */
      for (i = 0; i < n_dup; i++, sp += len + 1)
	{
	  memcpy (sp, cp, len);
	  *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
	}

      cp = ep;
    }
  while (cp != NULL);

  return result;
}

/* Alter the output of INSN whose pattern was modified by
   DEFINE_SUBST.  We must replicate output strings according
   to the new number of alternatives ALT in substituted pattern.
   If ALT equals 1, output has one alternative or defined by C
   code, then output is returned without any changes.  */

static const char *
alter_output_for_subst_insn (rtx insn, int alt)
{
  const char *insn_out, *old_out;
  char *new_out, *cp;
  size_t old_len, new_len;
  int j;

  insn_out = XTMPL (insn, 3);

  if (alt < 2 || *insn_out != '@')
    return insn_out;

  old_out = insn_out + 1;
  while (ISSPACE (*old_out))
    old_out++;
  old_len = strlen (old_out);

  new_len = alt * (old_len + 1) + 1;

  new_out = XNEWVEC (char, new_len);
  new_out[0] = '@';

  for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
    {
      memcpy (cp, old_out, old_len);
      cp[old_len] = (j == alt - 1) ? '\0' : '\n';
    }

  return new_out;
}

/* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */

static void
process_one_cond_exec (class queue_elem *ce_elem)
{
  class queue_elem *insn_elem;
  for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
    {
      int alternatives, max_operand;
      rtx pred, insn, pattern, split;
      char *new_name;
      int i;

      if (! is_predicable (insn_elem))
	continue;

      alternatives = 1;
      max_operand = -1;
      collect_insn_data (insn_elem->data, &alternatives, &max_operand);
      max_operand += 1;

      if (XVECLEN (ce_elem->data, 0) != 1)
	{
	  error_at (ce_elem->loc, "too many patterns in predicate");
	  return;
	}

      pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
      pred = alter_predicate_for_insn (pred, alternatives, max_operand,
				       ce_elem->loc);
      if (pred == NULL)
	return;

      /* Construct a new pattern for the new insn.  */
      insn = copy_rtx (insn_elem->data);
      new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
      sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
      XSTR (insn, 0) = new_name;
      pattern = rtx_alloc (COND_EXEC);
      XEXP (pattern, 0) = pred;
      XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
      XVEC (insn, 1) = rtvec_alloc (1);
      XVECEXP (insn, 1, 0) = pattern;

       if (XVEC (ce_elem->data, 3) != NULL)
	{
	  rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
	                                  + XVECLEN (ce_elem->data, 3));
	  int i = 0;
	  int j = 0;
	  for (i = 0; i < XVECLEN (insn, 4); i++)
	    RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);

	  for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
	    RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);

	  XVEC (insn, 4) = attributes;
	}

      XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
      XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
					      alternatives, max_operand);
      alter_attrs_for_insn (insn);

      /* Put the new pattern on the `other' list so that it
	 (a) is not reprocessed by other define_cond_exec patterns
	 (b) appears after all normal define_insn patterns.

	 ??? B is debatable.  If one has normal insns that match
	 cond_exec patterns, they will be preferred over these
	 generated patterns.  Whether this matters in practice, or if
	 it's a good thing, or whether we should thread these new
	 patterns into the define_insn chain just after their generator
	 is something we'll have to experiment with.  */

      queue_pattern (insn, &other_tail, insn_elem->loc);

      if (!insn_elem->split)
	continue;

      /* If the original insn came from a define_insn_and_split,
	 generate a new split to handle the predicated insn.  */
      split = copy_rtx (insn_elem->split->data);
      /* Predicate the pattern matched by the split.  */
      pattern = rtx_alloc (COND_EXEC);
      XEXP (pattern, 0) = pred;
      XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
      XVEC (split, 0) = rtvec_alloc (1);
      XVECEXP (split, 0, 0) = pattern;

      /* Predicate all of the insns generated by the split.  */
      for (i = 0; i < XVECLEN (split, 2); i++)
	{
	  pattern = rtx_alloc (COND_EXEC);
	  XEXP (pattern, 0) = pred;
	  XEXP (pattern, 1) = XVECEXP (split, 2, i);
	  XVECEXP (split, 2, i) = pattern;
	}
      /* Add the new split to the queue.  */
      queue_pattern (split, &other_tail, insn_elem->split->loc);
    }
}

/* Try to apply define_substs to the given ELEM.
   Only define_substs, specified via attributes would be applied.
   If attribute, requiring define_subst, is set, but no define_subst
   was applied, ELEM would be deleted.  */

static void
process_substs_on_one_elem (class queue_elem *elem,
			    class queue_elem *queue)
{
  class queue_elem *subst_elem;
  int i, j, patterns_match;

  for (subst_elem = define_subst_queue;
       subst_elem; subst_elem = subst_elem->next)
    {
      int alternatives, alternatives_subst;
      rtx subst_pattern;
      rtvec subst_pattern_vec;

      if (!has_subst_attribute (elem, subst_elem))
	continue;

      /* Compare original rtl-pattern from define_insn with input
	 pattern from define_subst.
	 Also, check if numbers of alternatives are the same in all
	 match_operands.  */
      if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
	continue;
      patterns_match = 1;
      alternatives = -1;
      alternatives_subst = -1;
      for (j = 0; j < XVECLEN (elem->data, 1); j++)
	{
	  if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
				    XVECEXP (subst_elem->data, 1, j),
				    subst_elem->loc))
	    {
	      patterns_match = 0;
	      break;
	    }

	  if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
					&alternatives, subst_elem->loc))
	    {
	      patterns_match = 0;
	      break;
	    }
	}

      /* Check if numbers of alternatives are the same in all
	 match_operands in output template of define_subst.  */
      for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
	{
	  if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
					&alternatives_subst,
					subst_elem->loc))
	    {
	      patterns_match = 0;
	      break;
	    }
	}

      if (!patterns_match)
	continue;

      /* Clear array in which we save occupied indexes of operands.  */
      memset (used_operands_numbers, 0, sizeof (used_operands_numbers));

      /* Create a pattern, based on the output one from define_subst.  */
      subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
      for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
	{
	  subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));

	  /* Duplicate constraints in substitute-pattern.  */
	  subst_pattern = alter_constraints (subst_pattern, alternatives,
					     duplicate_each_alternative);

	  subst_pattern = adjust_operands_numbers (subst_pattern);

	  /* Substitute match_dup and match_op_dup in the new pattern and
	     duplicate constraints.  */
	  subst_pattern = subst_dup (subst_pattern, alternatives,
				     alternatives_subst);

	  replace_duplicating_operands_in_pattern (subst_pattern);

	  /* We don't need any constraints in DEFINE_EXPAND.  */
	  if (GET_CODE (elem->data) == DEFINE_EXPAND)
	    remove_constraints (subst_pattern);

	  RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
	}
      XVEC (elem->data, 1) = subst_pattern_vec;

      for (i = 0; i < MAX_OPERANDS; i++)
	  match_operand_entries_in_pattern[i] = NULL;

      if (GET_CODE (elem->data) == DEFINE_INSN)
	{
	  XTMPL (elem->data, 3) =
	    alter_output_for_subst_insn (elem->data, alternatives_subst);
	  alter_attrs_for_subst_insn (elem, alternatives_subst);
	}

      /* Recalculate condition, joining conditions from original and
	 DEFINE_SUBST input patterns.  */
      XSTR (elem->data, 2)
	= rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
					     XSTR (elem->data, 2));
      /* Mark that subst was applied by changing attribute from "yes"
	 to "no".  */
      change_subst_attribute (elem, subst_elem, subst_false);
    }

  /* If ELEM contains a subst attribute with value "yes", then we
     expected that a subst would be applied, but it wasn't - so,
     we need to remove that elementto avoid duplicating.  */
  for (subst_elem = define_subst_queue;
       subst_elem; subst_elem = subst_elem->next)
    {
      if (has_subst_attribute (elem, subst_elem))
	{
	  remove_from_queue (elem, &queue);
	  return;
	}
    }
}

/* This is a subroutine of mark_operands_used_in_match_dup.
   This routine is marks all MATCH_OPERANDs inside PATTERN as occupied.  */
static void
mark_operands_from_match_dup (rtx pattern)
{
  const char *fmt;
  int i, j, len, opno;

  if (GET_CODE (pattern) == MATCH_OPERAND
      || GET_CODE (pattern) == MATCH_OPERATOR
      || GET_CODE (pattern) == MATCH_PARALLEL)
    {
      opno = XINT (pattern, 0);
      gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
      used_operands_numbers [opno] = 1;
    }
  fmt = GET_RTX_FORMAT (GET_CODE (pattern));
  len = GET_RTX_LENGTH (GET_CODE (pattern));
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  mark_operands_from_match_dup (XEXP (pattern, i));
	  break;
	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    mark_operands_from_match_dup (XVECEXP (pattern, i, j));
	  break;
	}
    }
}

/* This is a subroutine of adjust_operands_numbers.
   It goes through all expressions in PATTERN and when MATCH_DUP is
   met, all MATCH_OPERANDs inside it is marked as occupied.  The
   process of marking is done by routin mark_operands_from_match_dup.  */
static void
mark_operands_used_in_match_dup (rtx pattern)
{
  const char *fmt;
  int i, j, len, opno;

  if (GET_CODE (pattern) == MATCH_DUP)
    {
      opno = XINT (pattern, 0);
      gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
      mark_operands_from_match_dup (operand_data[opno]);
      return;
    }
  fmt = GET_RTX_FORMAT (GET_CODE (pattern));
  len = GET_RTX_LENGTH (GET_CODE (pattern));
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  mark_operands_used_in_match_dup (XEXP (pattern, i));
	  break;
	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
	  break;
	}
    }
}

/* This is subroutine of renumerate_operands_in_pattern.
   It finds first not-occupied operand-index.  */
static int
find_first_unused_number_of_operand ()
{
  int i;
  for (i = 0; i < MAX_OPERANDS; i++)
    if (!used_operands_numbers[i])
      return i;
  return MAX_OPERANDS;
}

/* This is subroutine of adjust_operands_numbers.
   It visits all expressions in PATTERN and assigns not-occupied
   operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
   PATTERN.  */
static void
renumerate_operands_in_pattern (rtx pattern)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len, new_opno;
  code = GET_CODE (pattern);

  if (code == MATCH_OPERAND
      || code == MATCH_OPERATOR)
    {
      new_opno = find_first_unused_number_of_operand ();
      gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
      XINT (pattern, 0) = new_opno;
      used_operands_numbers [new_opno] = 1;
    }

  fmt = GET_RTX_FORMAT (GET_CODE (pattern));
  len = GET_RTX_LENGTH (GET_CODE (pattern));
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  renumerate_operands_in_pattern (XEXP (pattern, i));
	  break;
	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
	  break;
	}
    }
}

/* If output pattern of define_subst contains MATCH_DUP, then this
   expression would be replaced with the pattern, matched with
   MATCH_OPERAND from input pattern.  This pattern could contain any
   number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
   that a MATCH_OPERAND from output_pattern (if any) would have the
   same number, as MATCH_OPERAND from copied pattern.  To avoid such
   indexes overlapping, we assign new indexes to MATCH_OPERANDs,
   laying in the output pattern outside of MATCH_DUPs.  */
static rtx
adjust_operands_numbers (rtx pattern)
{
  mark_operands_used_in_match_dup (pattern);

  renumerate_operands_in_pattern (pattern);

  return pattern;
}

/* Generate RTL expression
   (match_dup OPNO)
   */
static rtx
generate_match_dup (int opno)
{
  rtx return_rtx = rtx_alloc (MATCH_DUP);
  PUT_CODE (return_rtx, MATCH_DUP);
  XINT (return_rtx, 0) = opno;
  return return_rtx;
}

/* This routine checks all match_operands in PATTERN and if some of
   have the same index, it replaces all of them except the first one  to
   match_dup.
   Usually, match_operands with the same indexes are forbidden, but
   after define_subst copy an RTL-expression from original template,
   indexes of existed and just-copied match_operands could coincide.
   To fix it, we replace one of them with match_dup.  */
static rtx
replace_duplicating_operands_in_pattern (rtx pattern)
{
  const char *fmt;
  int i, j, len, opno;
  rtx mdup;

  if (GET_CODE (pattern) == MATCH_OPERAND)
    {
      opno = XINT (pattern, 0);
      gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
      if (match_operand_entries_in_pattern[opno] == NULL)
	{
	  match_operand_entries_in_pattern[opno] = pattern;
	  return NULL;
	}
      else
	{
	  /* Compare predicates before replacing with match_dup.  */
	  if (strcmp (XSTR (pattern, 1),
		      XSTR (match_operand_entries_in_pattern[opno], 1)))
	    {
	      error ("duplicated match_operands with different predicates were"
		     " found.");
	      return NULL;
	    }
	  return generate_match_dup (opno);
	}
    }
  fmt = GET_RTX_FORMAT (GET_CODE (pattern));
  len = GET_RTX_LENGTH (GET_CODE (pattern));
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
	  if (mdup)
	    XEXP (pattern, i) = mdup;
	  break;
	case 'E':
	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	    {
	      mdup =
		replace_duplicating_operands_in_pattern (XVECEXP
							 (pattern, i, j));
	      if (mdup)
		XVECEXP (pattern, i, j) = mdup;
	    }
	  break;
	}
    }
  return NULL;
}

/* The routine modifies given input PATTERN of define_subst, replacing
   MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
   pattern, whose operands are stored in OPERAND_DATA array.
   It also duplicates constraints in operands - constraints from
   define_insn operands are duplicated N_SUBST_ALT times, constraints
   from define_subst operands are duplicated N_ALT times.
   After the duplication, returned output rtl-pattern contains every
   combination of input constraints Vs constraints from define_subst
   output.  */
static rtx
subst_dup (rtx pattern, int n_alt, int n_subst_alt)
{
  const char *fmt;
  enum rtx_code code;
  int i, j, len, opno;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_DUP:
    case MATCH_OP_DUP:
      opno = XINT (pattern, 0);

      gcc_assert (opno >= 0 && opno < MAX_OPERANDS);

      if (operand_data[opno])
	{
	  pattern = copy_rtx (operand_data[opno]);

	  /* Duplicate constraints.  */
	  pattern = alter_constraints (pattern, n_subst_alt,
				       duplicate_alternatives);
	}
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (GET_CODE (pattern));
  len = GET_RTX_LENGTH (GET_CODE (pattern));
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
	    XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
					   n_alt, n_subst_alt);
	  break;
	case 'V':
	  if (XVEC (pattern, i) == NULL)
	    break;
	  /* FALLTHRU */
	case 'E':
	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
	    for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
	      XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
						   n_alt, n_subst_alt);
	  break;

	case 'r': case 'p': case 'i': case 'w':
	case '0': case 's': case 'S': case 'T':
	  break;

	default:
	  gcc_unreachable ();
	}
    }
  return pattern;
}

/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
   patterns appropriately.  */

static void
process_define_cond_exec (void)
{
  class queue_elem *elem;

  identify_predicable_attribute ();
  if (have_error)
    return;

  for (elem = define_cond_exec_queue; elem ; elem = elem->next)
    process_one_cond_exec (elem);
}

/* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
   DEFINE_EXPAND patterns appropriately.  */

static void
process_define_subst (void)
{
  class queue_elem *elem, *elem_attr;

  /* Check if each define_subst has corresponding define_subst_attr.  */
  for (elem = define_subst_queue; elem ; elem = elem->next)
    {
      for (elem_attr = define_subst_attr_queue;
	   elem_attr;
	   elem_attr = elem_attr->next)
	if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
	    goto found;

      error_at (elem->loc,
		"%s: `define_subst' must have at least one "
		"corresponding `define_subst_attr'",
		XSTR (elem->data, 0));
      return;

      found:
	continue;
    }

  for (elem = define_insn_queue; elem ; elem = elem->next)
    process_substs_on_one_elem (elem, define_insn_queue);
  for (elem = other_queue; elem ; elem = elem->next)
    {
      if (GET_CODE (elem->data) != DEFINE_EXPAND)
	continue;
      process_substs_on_one_elem (elem, other_queue);
    }
}

/* A subclass of rtx_reader which reads .md files and calls process_rtx on
   the top-level elements.  */

class gen_reader : public rtx_reader
{
 public:
  gen_reader () : rtx_reader (false) {}
  void handle_unknown_directive (file_location, const char *);
};

void
gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
{
  auto_vec<rtx, 32> subrtxs;
  if (!read_rtx (rtx_name, &subrtxs))
    return;

  rtx x;
  unsigned int i;
  FOR_EACH_VEC_ELT (subrtxs, i, x)
    process_rtx (x, loc);
}

/* Comparison function for the mnemonic hash table.  */

static int
htab_eq_string (const void *s1, const void *s2)
{
  return strcmp ((const char*)s1, (const char*)s2) == 0;
}

/* Add mnemonic STR with length LEN to the mnemonic hash table
   MNEMONIC_HTAB.  A trailing zero end character is appended to STR
   and a permanent heap copy of STR is created.  */

static void
add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
{
  char *new_str;
  void **slot;
  char *str_zero = (char*)alloca (len + 1);

  memcpy (str_zero, str, len);
  str_zero[len] = '\0';

  slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);

  if (*slot)
    return;

  /* Not found; create a permanent copy and add it to the hash table.  */
  new_str = XNEWVAR (char, len + 1);
  memcpy (new_str, str_zero, len + 1);
  *slot = new_str;
}

/* Scan INSN for mnemonic strings and add them to the mnemonic hash
   table in MNEMONIC_HTAB.

   The mnemonics cannot be found if they are emitted using C code.

   If a mnemonic string contains ';' or a newline the string assumed
   to consist of more than a single instruction.  The attribute value
   will then be set to the user defined default value.  */

static void
gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
{
  const char *template_code, *cp;
  int i;
  int vec_len;
  rtx set_attr;
  char *attr_name;
  rtvec new_vec;
  struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();

  template_code = XTMPL (insn, 3);

  /* Skip patterns which use C code to emit the template.  */
  if (template_code[0] == '*')
    return;

  if (template_code[0] == '@')
    cp = &template_code[1];
  else
    cp = &template_code[0];

  for (i = 0; *cp; )
    {
      const char *ep, *sp;
      size_t size = 0;

      while (ISSPACE (*cp))
	cp++;

      for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
	if (!ISSPACE (*ep))
	  sp = ep + 1;

      if (i > 0)
	obstack_1grow (string_obstack, ',');

      while (cp < sp && ((*cp >= '0' && *cp <= '9')
			 || (*cp >= 'a' && *cp <= 'z')))

	{
	  obstack_1grow (string_obstack, *cp);
	  cp++;
	  size++;
	}

      while (cp < sp)
	{
	  if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
	    {
	      /* Don't set a value if there are more than one
		 instruction in the string.  */
	      obstack_blank_fast (string_obstack, -size);
	      size = 0;

	      cp = sp;
	      break;
	    }
	  cp++;
	}
      if (size == 0)
	obstack_1grow (string_obstack, '*');
      else
	add_mnemonic_string (mnemonic_htab,
			     (char *) obstack_next_free (string_obstack) - size,
			     size);
      i++;
    }

  /* An insn definition might emit an empty string.  */
  if (obstack_object_size (string_obstack) == 0)
    return;

  obstack_1grow (string_obstack, '\0');

  set_attr = rtx_alloc (SET_ATTR);
  XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
  attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
  strcpy (attr_name, MNEMONIC_ATTR_NAME);
  XSTR (set_attr, 0) = attr_name;

  if (!XVEC (insn, 4))
    vec_len = 0;
  else
    vec_len = XVECLEN (insn, 4);

  new_vec = rtvec_alloc (vec_len + 1);
  for (i = 0; i < vec_len; i++)
    RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
  RTVEC_ELT (new_vec, vec_len) = set_attr;
  XVEC (insn, 4) = new_vec;
}

/* This function is called for the elements in the mnemonic hashtable
   and generates a comma separated list of the mnemonics.  */

static int
mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
{
  struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();

  obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
  obstack_1grow (string_obstack, ',');
  return 1;
}

/* Generate (set_attr "mnemonic" "..") RTXs and append them to every
   insn definition in case the back end requests it by defining the
   mnemonic attribute.  The values for the attribute will be extracted
   from the output patterns of the insn definitions as far as
   possible.  */

static void
gen_mnemonic_attr (void)
{
  class queue_elem *elem;
  rtx mnemonic_attr = NULL;
  htab_t mnemonic_htab;
  const char *str, *p;
  int i;
  struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();

  if (have_error)
    return;

  /* Look for the DEFINE_ATTR for `mnemonic'.  */
  for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
    if (GET_CODE (elem->data) == DEFINE_ATTR
	&& strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
      {
	mnemonic_attr = elem->data;
	break;
      }

  /* A (define_attr "mnemonic" "...") indicates that the back-end
     wants a mnemonic attribute to be generated.  */
  if (!mnemonic_attr)
    return;

  mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
				     htab_eq_string, 0, xcalloc, free);

  for (elem = define_insn_queue; elem; elem = elem->next)
    {
      rtx insn = elem->data;
      bool found = false;

      /* Check if the insn definition already has
	 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...).  */
      if (XVEC (insn, 4))
 	for (i = 0; i < XVECLEN (insn, 4); i++)
	  {
	    rtx set_attr = XVECEXP (insn, 4, i);

	    switch (GET_CODE (set_attr))
	      {
	      case SET_ATTR:
	      case SET_ATTR_ALTERNATIVE:
		if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
		  found = true;
		break;
	      case SET:
		if (GET_CODE (SET_DEST (set_attr)) == ATTR
		    && strcmp (XSTR (SET_DEST (set_attr), 0),
			       MNEMONIC_ATTR_NAME) == 0)
		  found = true;
		break;
	      default:
		break;
	      }
	  }

      if (!found)
	gen_mnemonic_setattr (mnemonic_htab, insn);
    }

  /* Add the user defined values to the hash table.  */
  str = XSTR (mnemonic_attr, 1);
  while ((p = scan_comma_elt (&str)) != NULL)
    add_mnemonic_string (mnemonic_htab, p, str - p);

  htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);

  /* Replace the last ',' with the zero end character.  */
  *((char *) obstack_next_free (string_obstack) - 1) = '\0';
  XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
}

/* Check if there are DEFINE_ATTRs with the same name.  */
static void
check_define_attr_duplicates ()
{
  class queue_elem *elem;
  htab_t attr_htab;
  char * attr_name;
  void **slot;

  attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);

  for (elem = define_attr_queue; elem; elem = elem->next)
    {
      attr_name = xstrdup (XSTR (elem->data, 0));

      slot = htab_find_slot (attr_htab, attr_name, INSERT);

      /* Duplicate.  */
      if (*slot)
	{
	  error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
	  htab_delete (attr_htab);
	  return;
	}

      *slot = attr_name;
    }

  htab_delete (attr_htab);
}

/* The entry point for initializing the reader.  */

rtx_reader *
init_rtx_reader_args_cb (int argc, const char **argv,
			 bool (*parse_opt) (const char *))
{
  /* Prepare to read input.  */
  condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
  init_predicate_table ();
  obstack_init (rtl_obstack);

  /* Start at 1, to make 0 available for CODE_FOR_nothing.  */
  insn_sequence_num = 1;

  /* These sequences are not used as indices, so can start at 1 also.  */
  split_sequence_num = 1;
  peephole2_sequence_num = 1;

  gen_reader *reader = new gen_reader ();
  reader->read_md_files (argc, argv, parse_opt);

  if (define_attr_queue != NULL)
    check_define_attr_duplicates ();

  /* Process define_cond_exec patterns.  */
  if (define_cond_exec_queue != NULL)
    process_define_cond_exec ();

  /* Process define_subst patterns.  */
  if (define_subst_queue != NULL)
    process_define_subst ();

  if (define_attr_queue != NULL)
    gen_mnemonic_attr ();

  if (have_error)
    {
      delete reader;
      return NULL;
    }

  return reader;
}

/* Programs that don't have their own options can use this entry point
   instead.  */
rtx_reader *
init_rtx_reader_args (int argc, const char **argv)
{
  return init_rtx_reader_args_cb (argc, argv, 0);
}

/* Try to read a single rtx from the file.  Return true on success,
   describing it in *INFO.  */

bool
read_md_rtx (md_rtx_info *info)
{
  int truth, *counter;
  rtx def;

  /* Discard insn patterns which we know can never match (because
     their C test is provably always false).  If insn_elision is
     false, our caller needs to see all the patterns.  Note that the
     elided patterns are never counted by the sequence numbering; it
     is the caller's responsibility, when insn_elision is false, not
     to use elided pattern numbers for anything.  */
  do
    {
      class queue_elem **queue, *elem;

      /* Read all patterns from a given queue before moving on to the next.  */
      if (define_attr_queue != NULL)
	queue = &define_attr_queue;
      else if (define_pred_queue != NULL)
	queue = &define_pred_queue;
      else if (define_insn_queue != NULL)
	queue = &define_insn_queue;
      else if (other_queue != NULL)
	queue = &other_queue;
      else
	return false;

      elem = *queue;
      *queue = elem->next;
      def = elem->data;
      info->def = def;
      info->loc = elem->loc;
      free (elem);

      truth = maybe_eval_c_test (get_c_test (def));
    }
  while (truth == 0 && insn_elision);

  /* Perform code-specific processing and pick the appropriate sequence
     number counter.  */
  switch (GET_CODE (def))
    {
    case DEFINE_INSN:
    case DEFINE_EXPAND:
      /* insn_sequence_num is used here so the name table will match caller's
	 idea of insn numbering, whether or not elision is active.  */
      record_insn_name (insn_sequence_num, XSTR (def, 0));

      /* Fall through.  */
    case DEFINE_PEEPHOLE:
      counter = &insn_sequence_num;
      break;

    case DEFINE_SPLIT:
      counter = &split_sequence_num;
      break;

    case DEFINE_PEEPHOLE2:
      counter = &peephole2_sequence_num;
      break;

    default:
      counter = NULL;
      break;
    }

  if (counter)
    {
      info->index = *counter;
      if (truth != 0)
	*counter += 1;
    }
  else
    info->index = -1;

  if (!rtx_locs)
    rtx_locs = new hash_map <rtx, file_location>;
  rtx_locs->put (info->def, info->loc);

  return true;
}

/* Return the file location of DEFINE_* rtx X, which was previously
   returned by read_md_rtx.  */
file_location
get_file_location (rtx x)
{
  gcc_assert (rtx_locs);
  file_location *entry = rtx_locs->get (x);
  gcc_assert (entry);
  return *entry;
}

/* Return the number of possible INSN_CODEs.  Only meaningful once the
   whole file has been processed.  */
unsigned int
get_num_insn_codes ()
{
  return insn_sequence_num;
}

/* Return the C test that says whether definition rtx DEF can be used,
   or "" if it can be used unconditionally.  */

const char *
get_c_test (rtx x)
{
  switch (GET_CODE (x))
    {
    case DEFINE_INSN:
    case DEFINE_EXPAND:
    case DEFINE_SUBST:
      return XSTR (x, 2);

    case DEFINE_SPLIT:
    case DEFINE_PEEPHOLE:
    case DEFINE_PEEPHOLE2:
      return XSTR (x, 1);

    default:
      return "";
    }
}

/* Helper functions for insn elision.  */

/* Compute a hash function of a c_test structure, which is keyed
   by its ->expr field.  */
hashval_t
hash_c_test (const void *x)
{
  const struct c_test *a = (const struct c_test *) x;
  const unsigned char *base, *s = (const unsigned char *) a->expr;
  hashval_t hash;
  unsigned char c;
  unsigned int len;

  base = s;
  hash = 0;

  while ((c = *s++) != '\0')
    {
      hash += c + (c << 17);
      hash ^= hash >> 2;
    }

  len = s - base;
  hash += len + (len << 17);
  hash ^= hash >> 2;

  return hash;
}

/* Compare two c_test expression structures.  */
int
cmp_c_test (const void *x, const void *y)
{
  const struct c_test *a = (const struct c_test *) x;
  const struct c_test *b = (const struct c_test *) y;

  return !strcmp (a->expr, b->expr);
}

/* Given a string representing a C test expression, look it up in the
   condition_table and report whether or not its value is known
   at compile time.  Returns a tristate: 1 for known true, 0 for
   known false, -1 for unknown.  */
int
maybe_eval_c_test (const char *expr)
{
  const struct c_test *test;
  struct c_test dummy;

  if (expr[0] == 0)
    return 1;

  dummy.expr = expr;
  test = (const struct c_test *)htab_find (condition_table, &dummy);
  if (!test)
    return -1;
  return test->value;
}

/* Record the C test expression EXPR in the condition_table, with
   value VAL.  Duplicates clobber previous entries.  */

void
add_c_test (const char *expr, int value)
{
  struct c_test *test;

  if (expr[0] == 0)
    return;

  test = XNEW (struct c_test);
  test->expr = expr;
  test->value = value;

  *(htab_find_slot (condition_table, test, INSERT)) = test;
}

/* For every C test, call CALLBACK with two arguments: a pointer to
   the condition structure and INFO.  Stops when CALLBACK returns zero.  */
void
traverse_c_tests (htab_trav callback, void *info)
{
  if (condition_table)
    htab_traverse (condition_table, callback, info);
}

/* Helper functions for define_predicate and define_special_predicate
   processing.  Shared between genrecog.c and genpreds.c.  */

static htab_t predicate_table;
struct pred_data *first_predicate;
static struct pred_data **last_predicate = &first_predicate;

static hashval_t
hash_struct_pred_data (const void *ptr)
{
  return htab_hash_string (((const struct pred_data *)ptr)->name);
}

static int
eq_struct_pred_data (const void *a, const void *b)
{
  return !strcmp (((const struct pred_data *)a)->name,
		  ((const struct pred_data *)b)->name);
}

struct pred_data *
lookup_predicate (const char *name)
{
  struct pred_data key;
  key.name = name;
  return (struct pred_data *) htab_find (predicate_table, &key);
}

/* Record that predicate PRED can accept CODE.  */

void
add_predicate_code (struct pred_data *pred, enum rtx_code code)
{
  if (!pred->codes[code])
    {
      pred->num_codes++;
      pred->codes[code] = true;

      if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
	pred->allows_non_const = true;

      if (code != REG
	  && code != SUBREG
	  && code != MEM
	  && code != CONCAT
	  && code != PARALLEL
	  && code != STRICT_LOW_PART
	  && code != ZERO_EXTRACT
	  && code != SCRATCH)
	pred->allows_non_lvalue = true;

      if (pred->num_codes == 1)
	pred->singleton = code;
      else if (pred->num_codes == 2)
	pred->singleton = UNKNOWN;
    }
}

void
add_predicate (struct pred_data *pred)
{
  void **slot = htab_find_slot (predicate_table, pred, INSERT);
  if (*slot)
    {
      error ("duplicate predicate definition for '%s'", pred->name);
      return;
    }
  *slot = pred;
  *last_predicate = pred;
  last_predicate = &pred->next;
}

/* This array gives the initial content of the predicate table.  It
   has entries for all predicates defined in recog.c.  */

struct std_pred_table
{
  const char *name;
  bool special;
  bool allows_const_p;
  RTX_CODE codes[NUM_RTX_CODE];
};

static const struct std_pred_table std_preds[] = {
  {"general_operand", false, true, {SUBREG, REG, MEM}},
  {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
				   ZERO_EXTEND, SIGN_EXTEND, AND}},
  {"register_operand", false, false, {SUBREG, REG}},
  {"pmode_register_operand", true, false, {SUBREG, REG}},
  {"scratch_operand", false, false, {SCRATCH, REG}},
  {"immediate_operand", false, true, {UNKNOWN}},
  {"const_int_operand", false, false, {CONST_INT}},
#if TARGET_SUPPORTS_WIDE_INT
  {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
  {"const_double_operand", false, false, {CONST_DOUBLE}},
#else
  {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
#endif
  {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
  {"nonmemory_operand", false, true, {SUBREG, REG}},
  {"push_operand", false, false, {MEM}},
  {"pop_operand", false, false, {MEM}},
  {"memory_operand", false, false, {SUBREG, MEM}},
  {"indirect_operand", false, false, {SUBREG, MEM}},
  {"ordered_comparison_operator", false, false, {EQ, NE,
						 LE, LT, GE, GT,
						 LEU, LTU, GEU, GTU}},
  {"comparison_operator", false, false, {EQ, NE,
					 LE, LT, GE, GT,
					 LEU, LTU, GEU, GTU,
					 UNORDERED, ORDERED,
					 UNEQ, UNGE, UNGT,
					 UNLE, UNLT, LTGT}}
};
#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)

/* Initialize the table of predicate definitions, starting with
   the information we have on generic predicates.  */

static void
init_predicate_table (void)
{
  size_t i, j;
  struct pred_data *pred;

  predicate_table = htab_create_alloc (37, hash_struct_pred_data,
				       eq_struct_pred_data, 0,
				       xcalloc, free);

  for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
    {
      pred = XCNEW (struct pred_data);
      pred->name = std_preds[i].name;
      pred->special = std_preds[i].special;

      for (j = 0; std_preds[i].codes[j] != 0; j++)
	add_predicate_code (pred, std_preds[i].codes[j]);

      if (std_preds[i].allows_const_p)
	for (j = 0; j < NUM_RTX_CODE; j++)
	  if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
	    add_predicate_code (pred, (enum rtx_code) j);

      add_predicate (pred);
    }
}

/* These functions allow linkage with print-rtl.c.  Also, some generators
   like to annotate their output with insn names.  */

/* Holds an array of names indexed by insn_code_number.  */
static char **insn_name_ptr = 0;
static int insn_name_ptr_size = 0;

const char *
get_insn_name (int code)
{
  if (code < insn_name_ptr_size)
    return insn_name_ptr[code];
  else
    return NULL;
}

static void
record_insn_name (int code, const char *name)
{
  static const char *last_real_name = "insn";
  static int last_real_code = 0;
  char *new_name;

  if (insn_name_ptr_size <= code)
    {
      int new_size;
      new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
      insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
      memset (insn_name_ptr + insn_name_ptr_size, 0,
	      sizeof (char *) * (new_size - insn_name_ptr_size));
      insn_name_ptr_size = new_size;
    }

  if (!name || name[0] == '\0')
    {
      new_name = XNEWVAR (char, strlen (last_real_name) + 10);
      sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
    }
  else
    {
      last_real_name = new_name = xstrdup (name);
      last_real_code = code;
    }

  insn_name_ptr[code] = new_name;
}

/* Make STATS describe the operands that appear in rtx X.  */

static void
get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
{
  RTX_CODE code;
  int i;
  int len;
  const char *fmt;

  if (x == NULL_RTX)
    return;

  code = GET_CODE (x);
  switch (code)
    {
    case MATCH_OPERAND:
    case MATCH_OPERATOR:
    case MATCH_PARALLEL:
      stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
      break;

    case MATCH_DUP:
    case MATCH_OP_DUP:
    case MATCH_PAR_DUP:
      stats->num_dups++;
      stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
      break;

    case MATCH_SCRATCH:
      if (stats->min_scratch_opno == -1)
	stats->min_scratch_opno = XINT (x, 0);
      else
	stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
      stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      if (fmt[i] == 'e' || fmt[i] == 'u')
	get_pattern_stats_1 (stats, XEXP (x, i));
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    get_pattern_stats_1 (stats, XVECEXP (x, i, j));
	}
    }
}

/* Make STATS describe the operands that appear in instruction pattern
   PATTERN.  */

void
get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
{
  int i, len;

  stats->max_opno = -1;
  stats->max_dup_opno = -1;
  stats->min_scratch_opno = -1;
  stats->max_scratch_opno = -1;
  stats->num_dups = 0;

  len = GET_NUM_ELEM (pattern);
  for (i = 0; i < len; i++)
    get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));

  stats->num_generator_args = stats->max_opno + 1;
  stats->num_insn_operands = MAX (stats->max_opno,
				  stats->max_scratch_opno) + 1;
  stats->num_operand_vars = MAX (stats->max_opno,
				  MAX (stats->max_dup_opno,
				       stats->max_scratch_opno)) + 1;
}

/* Return the emit_* function that should be used for pattern X, or NULL
   if we can't pick a particular type at compile time and should instead
   fall back to "emit".  */

const char *
get_emit_function (rtx x)
{
  switch (classify_insn (x))
    {
    case INSN:
      return "emit_insn";

    case CALL_INSN:
      return "emit_call_insn";

    case JUMP_INSN:
      return "emit_jump_insn";

    case UNKNOWN:
      return NULL;

    default:
      gcc_unreachable ();
    }
}

/* Return true if we must emit a barrier after pattern X.  */

bool
needs_barrier_p (rtx x)
{
  return (GET_CODE (x) == SET
	  && GET_CODE (SET_DEST (x)) == PC
	  && GET_CODE (SET_SRC (x)) == LABEL_REF);
}

#define NS "NULL"
#define ZS "'\\0'"
#define OPTAB_CL(o, p, c, b, l)    { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
#define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
#define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
#define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
#define OPTAB_NC(o, p, c)          { #o, p, NS, ZS, NS, o, c, c, 3 },
#define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
#define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
#define OPTAB_VC(o, p, c)          { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
#define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
#define OPTAB_DC(o, p, c)          { #o, p, NS, ZS, NS, o, c, c, 4 },
#define OPTAB_D(o, p)  { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },

/* An array of all optabs.  Note that the same optab can appear more
   than once, with a different pattern.  */
optab_def optabs[] = {
  { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
#include "optabs.def"
};

/* The number of entries in optabs[].  */
unsigned int num_optabs = ARRAY_SIZE (optabs);

#undef OPTAB_CL
#undef OPTAB_CX
#undef OPTAB_CD
#undef OPTAB_NL
#undef OPTAB_NC
#undef OPTAB_NX
#undef OPTAB_VL
#undef OPTAB_VC
#undef OPTAB_VX
#undef OPTAB_DC
#undef OPTAB_D

/* Return true if instruction NAME matches pattern PAT, storing information
   about the match in P if so.  */

static bool
match_pattern (optab_pattern *p, const char *name, const char *pat)
{
  bool force_float = false;
  bool force_int = false;
  bool force_partial_int = false;
  bool force_fixed = false;

  if (pat == NULL)
    return false;
  for (; ; ++pat)
    {
      if (*pat != '$')
	{
	  if (*pat != *name++)
	    return false;
	  if (*pat == '\0')
	    return true;
	  continue;
	}
      switch (*++pat)
	{
	case 'I':
	  force_int = 1;
	  break;
	case 'P':
	  force_partial_int = 1;
	  break;
	case 'F':
	  force_float = 1;
	  break;
	case 'Q':
	  force_fixed = 1;
	  break;

	case 'a':
	case 'b':
	  {
	    int i;

	    /* This loop will stop at the first prefix match, so
	       look through the modes in reverse order, in case
	       there are extra CC modes and CC is a prefix of the
	       CC modes (as it should be).  */
	    for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
	      {
		const char *p, *q;
		for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
		  if (TOLOWER (*p) != *q)
		    break;
		if (*p == 0
		    && (! force_int || mode_class[i] == MODE_INT
			|| mode_class[i] == MODE_VECTOR_INT)
		    && (! force_partial_int
			|| mode_class[i] == MODE_INT
			|| mode_class[i] == MODE_PARTIAL_INT
			|| mode_class[i] == MODE_VECTOR_INT)
		    && (! force_float
			|| mode_class[i] == MODE_FLOAT
			|| mode_class[i] == MODE_DECIMAL_FLOAT
			|| mode_class[i] == MODE_COMPLEX_FLOAT
			|| mode_class[i] == MODE_VECTOR_FLOAT)
		    && (! force_fixed
			|| mode_class[i] == MODE_FRACT
			|| mode_class[i] == MODE_UFRACT
			|| mode_class[i] == MODE_ACCUM
			|| mode_class[i] == MODE_UACCUM
			|| mode_class[i] == MODE_VECTOR_FRACT
			|| mode_class[i] == MODE_VECTOR_UFRACT
			|| mode_class[i] == MODE_VECTOR_ACCUM
			|| mode_class[i] == MODE_VECTOR_UACCUM))
		  break;
	      }

	    if (i < 0)
	      return false;
	    name += strlen (GET_MODE_NAME (i));
	    if (*pat == 'a')
	      p->m1 = i;
	    else
	      p->m2 = i;

	    force_int = false;
	    force_partial_int = false;
	    force_float = false;
	    force_fixed = false;
	  }
	  break;

	default:
	  gcc_unreachable ();
	}
    }
}

/* Return true if NAME is the name of an optab, describing it in P if so.  */

bool
find_optab (optab_pattern *p, const char *name)
{
  if (*name == 0 || *name == '*')
    return false;

  /* See if NAME matches one of the patterns we have for the optabs
     we know about.  */
  for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
    {
      p->m1 = p->m2 = 0;
      if (match_pattern (p, name, optabs[pindex].pattern))
	{
	  p->name = name;
	  p->op = optabs[pindex].op;
	  p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
	  return true;
	}
    }
  return false;
}
