/* Generate code from machine description to recognize rtl as insns.
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998,
   1999, 2000, 2001, 2002, 2003, 2004 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 2, 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 COPYING.  If not, write to the Free
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */


/* This program is used to produce insn-recog.c, which contains a
   function called `recog' plus its subroutines.  These functions
   contain a decision tree that recognizes whether an rtx, the
   argument given to recog, is a valid instruction.

   recog returns -1 if the rtx is not valid.  If the rtx is valid,
   recog returns a nonnegative number which is the insn code number
   for the pattern that matched.  This is the same as the order in the
   machine description of the entry that matched.  This number can be
   used as an index into various insn_* tables, such as insn_template,
   insn_outfun, and insn_n_operands (found in insn-output.c).

   The third argument to recog is an optional pointer to an int.  If
   present, recog will accept a pattern if it matches except for
   missing CLOBBER expressions at the end.  In that case, the value
   pointed to by the optional pointer will be set to the number of
   CLOBBERs that need to be added (it should be initialized to zero by
   the caller).  If it is set nonzero, the caller should allocate a
   PARALLEL of the appropriate size, copy the initial entries, and
   call add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.

   This program also generates the function `split_insns', which
   returns 0 if the rtl could not be split, or it returns the split
   rtl as an INSN list.

   This program also generates the function `peephole2_insns', which
   returns 0 if the rtl could not be matched.  If there was a match,
   the new rtl is returned in an INSN list, and LAST_INSN will point
   to the last recognized insn in the old sequence.  */

#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"


#define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
  printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER))

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

/* A listhead of decision trees.  The alternatives to a node are kept
   in a doubly-linked list so we can easily add nodes to the proper
   place when merging.  */

struct decision_head
{
  struct decision *first;
  struct decision *last;
};

/* A single test.  The two accept types aren't tests per-se, but
   their equality (or lack thereof) does affect tree merging so
   it is convenient to keep them here.  */

struct decision_test
{
  /* A linked list through the tests attached to a node.  */
  struct decision_test *next;

  /* These types are roughly in the order in which we'd like to test them.  */
  enum decision_type
    {
      DT_mode, DT_code, DT_veclen,
      DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
      DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
      DT_accept_op, DT_accept_insn
    } type;

  union
  {
    enum machine_mode mode;	/* Machine mode of node.  */
    RTX_CODE code;		/* Code to test.  */

    struct
    {
      const char *name;		/* Predicate to call.  */
      int index;		/* Index into `preds' or -1.  */
      enum machine_mode mode;	/* Machine mode for node.  */
    } pred;

    const char *c_test;		/* Additional test to perform.  */
    int veclen;			/* Length of vector.  */
    int dup;			/* Number of operand to compare against.  */
    HOST_WIDE_INT intval;	/* Value for XINT for XWINT.  */
    int opno;			/* Operand number matched.  */

    struct {
      int code_number;		/* Insn number matched.  */
      int lineno;		/* Line number of the insn.  */
      int num_clobbers_to_add;	/* Number of CLOBBERs to be added.  */
    } insn;
  } u;
};

/* Data structure for decision tree for recognizing legitimate insns.  */

struct decision
{
  struct decision_head success;	/* Nodes to test on success.  */
  struct decision *next;	/* Node to test on failure.  */
  struct decision *prev;	/* Node whose failure tests us.  */
  struct decision *afterward;	/* Node to test on success,
				   but failure of successor nodes.  */

  const char *position;		/* String denoting position in pattern.  */

  struct decision_test *tests;	/* The tests for this node.  */

  int number;			/* Node number, used for labels */
  int subroutine_number;	/* Number of subroutine this node starts */
  int need_label;		/* Label needs to be output.  */
};

#define SUBROUTINE_THRESHOLD	100

static int next_subroutine_number;

/* We can write three types of subroutines: One for insn recognition,
   one to split insns, and one for peephole-type optimizations.  This
   defines which type is being written.  */

enum routine_type {
  RECOG, SPLIT, PEEPHOLE2
};

#define IS_SPLIT(X) ((X) != RECOG)

/* Next available node number for tree nodes.  */

static int next_number;

/* Next number to use as an insn_code.  */

static int next_insn_code;

/* Similar, but counts all expressions in the MD file; used for
   error messages.  */

static int next_index;

/* Record the highest depth we ever have so we know how many variables to
   allocate in each subroutine we make.  */

static int max_depth;

/* The line number of the start of the pattern currently being processed.  */
static int pattern_lineno;

/* Count of errors.  */
static int error_count;

/* This table contains a list of the rtl codes that can possibly match a
   predicate defined in recog.c.  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.  */

static const struct pred_table
{
  const char *const name;
  const RTX_CODE codes[NUM_RTX_CODE];
} preds[] = {
  {"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
		       LABEL_REF, SUBREG, REG, MEM, ADDRESSOF}},
#ifdef PREDICATE_CODES
  PREDICATE_CODES
#endif
  {"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
		       LABEL_REF, SUBREG, REG, MEM, ADDRESSOF,
		       PLUS, MINUS, MULT}},
  {"register_operand", {SUBREG, REG, ADDRESSOF}},
  {"pmode_register_operand", {SUBREG, REG, ADDRESSOF}},
  {"scratch_operand", {SCRATCH, REG}},
  {"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
			 LABEL_REF}},
  {"const_int_operand", {CONST_INT}},
  {"const_double_operand", {CONST_INT, CONST_DOUBLE}},
  {"nonimmediate_operand", {SUBREG, REG, MEM, ADDRESSOF}},
  {"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
			 LABEL_REF, SUBREG, REG, ADDRESSOF}},
  {"push_operand", {MEM}},
  {"pop_operand", {MEM}},
  {"memory_operand", {SUBREG, MEM}},
  {"indirect_operand", {SUBREG, MEM}},
  {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
			   UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
			   UNLT, LTGT}}
};

#define NUM_KNOWN_PREDS ARRAY_SIZE (preds)

static const char *const special_mode_pred_table[] = {
#ifdef SPECIAL_MODE_PREDICATES
  SPECIAL_MODE_PREDICATES
#endif
  "pmode_register_operand"
};

#define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)

static struct decision *new_decision
  (const char *, struct decision_head *);
static struct decision_test *new_decision_test
  (enum decision_type, struct decision_test ***);
static rtx find_operand
  (rtx, int, rtx);
static rtx find_matching_operand
  (rtx, int);
static void validate_pattern
  (rtx, rtx, rtx, int);
static struct decision *add_to_sequence
  (rtx, struct decision_head *, const char *, enum routine_type, int);

static int maybe_both_true_2
  (struct decision_test *, struct decision_test *);
static int maybe_both_true_1
  (struct decision_test *, struct decision_test *);
static int maybe_both_true
  (struct decision *, struct decision *, int);

static int nodes_identical_1
  (struct decision_test *, struct decision_test *);
static int nodes_identical
  (struct decision *, struct decision *);
static void merge_accept_insn
  (struct decision *, struct decision *);
static void merge_trees
  (struct decision_head *, struct decision_head *);

static void factor_tests
  (struct decision_head *);
static void simplify_tests
  (struct decision_head *);
static int break_out_subroutines
  (struct decision_head *, int);
static void find_afterward
  (struct decision_head *, struct decision *);

static void change_state
  (const char *, const char *, struct decision *, const char *);
static void print_code
  (enum rtx_code);
static void write_afterward
  (struct decision *, struct decision *, const char *);
static struct decision *write_switch
  (struct decision *, int);
static void write_cond
  (struct decision_test *, int, enum routine_type);
static void write_action
  (struct decision *, struct decision_test *, int, int,
   struct decision *, enum routine_type);
static int is_unconditional
  (struct decision_test *, enum routine_type);
static int write_node
  (struct decision *, int, enum routine_type);
static void write_tree_1
  (struct decision_head *, int, enum routine_type);
static void write_tree
  (struct decision_head *, const char *, enum routine_type, int);
static void write_subroutine
  (struct decision_head *, enum routine_type);
static void write_subroutines
  (struct decision_head *, enum routine_type);
static void write_header
  (void);

static struct decision_head make_insn_sequence
  (rtx, enum routine_type);
static void process_tree
  (struct decision_head *, enum routine_type);

static void record_insn_name
  (int, const char *);

static void debug_decision_0
  (struct decision *, int, int);
static void debug_decision_1
  (struct decision *, int);
static void debug_decision_2
  (struct decision_test *);
extern void debug_decision
  (struct decision *);
extern void debug_decision_list
  (struct decision *);

/* Create a new node in sequence after LAST.  */

static struct decision *
new_decision (const char *position, struct decision_head *last)
{
  struct decision *new = xcalloc (1, sizeof (struct decision));

  new->success = *last;
  new->position = xstrdup (position);
  new->number = next_number++;

  last->first = last->last = new;
  return new;
}

/* Create a new test and link it in at PLACE.  */

static struct decision_test *
new_decision_test (enum decision_type type, struct decision_test ***pplace)
{
  struct decision_test **place = *pplace;
  struct decision_test *test;

  test = xmalloc (sizeof (*test));
  test->next = *place;
  test->type = type;
  *place = test;

  place = &test->next;
  *pplace = place;

  return test;
}

/* Search for and return operand N, stop when reaching node STOP.  */

static rtx
find_operand (rtx pattern, int n, rtx stop)
{
  const char *fmt;
  RTX_CODE code;
  int i, j, len;
  rtx r;

  if (pattern == stop)
    return stop;

  code = GET_CODE (pattern);
  if ((code == MATCH_SCRATCH
       || code == MATCH_INSN
       || code == MATCH_OPERAND
       || code == MATCH_OPERATOR
       || code == MATCH_PARALLEL)
      && XINT (pattern, 0) == n)
    return pattern;

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX)
	    return r;
	  break;

	case 'V':
	  if (! XVEC (pattern, i))
	    break;
	  /* Fall through.  */

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    if ((r = find_operand (XVECEXP (pattern, i, j), n, stop))
		!= NULL_RTX)
	      return r;
	  break;

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

	default:
	  abort ();
	}
    }

  return NULL;
}

/* Search for and return operand M, such that it has a matching
   constraint for operand N.  */

static rtx
find_matching_operand (rtx pattern, int n)
{
  const char *fmt;
  RTX_CODE code;
  int i, j, len;
  rtx r;

  code = GET_CODE (pattern);
  if (code == MATCH_OPERAND
      && (XSTR (pattern, 2)[0] == '0' + n
	  || (XSTR (pattern, 2)[0] == '%'
	      && XSTR (pattern, 2)[1] == '0' + n)))
    return pattern;

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

	case 'V':
	  if (! XVEC (pattern, i))
	    break;
	  /* Fall through.  */

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    if ((r = find_matching_operand (XVECEXP (pattern, i, j), n)))
	      return r;
	  break;

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

	default:
	  abort ();
	}
    }

  return NULL;
}


/* Check for various errors in patterns.  SET is nonnull for a destination,
   and is the complete set pattern.  SET_CODE is '=' for normal sets, and
   '+' within a context that requires in-out constraints.  */

static void
validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
{
  const char *fmt;
  RTX_CODE code;
  size_t i, len;
  int j;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_SCRATCH:
      return;
    case MATCH_DUP:
    case MATCH_OP_DUP:
    case MATCH_PAR_DUP:
      if (find_operand (insn, XINT (pattern, 0), pattern) == pattern)
	{
	  message_with_line (pattern_lineno,
			     "operand %i duplicated before defined",
			     XINT (pattern, 0));
          error_count++;
	}
      break;
    case MATCH_INSN:
    case MATCH_OPERAND:
    case MATCH_OPERATOR:
      {
	const char *pred_name = XSTR (pattern, 1);
	int allows_non_lvalue = 1, allows_non_const = 1;
	int special_mode_pred = 0;
	const char *c_test;

	if (GET_CODE (insn) == DEFINE_INSN)
	  c_test = XSTR (insn, 2);
	else
	  c_test = XSTR (insn, 1);

	if (pred_name[0] != 0)
	  {
	    for (i = 0; i < NUM_KNOWN_PREDS; i++)
	      if (! strcmp (preds[i].name, pred_name))
		break;

	    if (i < NUM_KNOWN_PREDS)
	      {
		int j;

		allows_non_lvalue = allows_non_const = 0;
		for (j = 0; preds[i].codes[j] != 0; j++)
		  {
		    RTX_CODE c = preds[i].codes[j];
		    if (c != LABEL_REF
			&& c != SYMBOL_REF
			&& c != CONST_INT
			&& c != CONST_DOUBLE
			&& c != CONST
			&& c != HIGH
			&& c != CONSTANT_P_RTX)
		      allows_non_const = 1;

		    if (c != REG
			&& c != SUBREG
			&& c != MEM
			&& c != ADDRESSOF
			&& c != CONCAT
			&& c != PARALLEL
			&& c != STRICT_LOW_PART)
		      allows_non_lvalue = 1;
		  }
	      }
	    else
	      {
#ifdef PREDICATE_CODES
		/* If the port has a list of the predicates it uses but
		   omits one, warn.  */
		message_with_line (pattern_lineno,
				   "warning: `%s' not in PREDICATE_CODES",
				   pred_name);
#endif
	      }

	    for (i = 0; i < NUM_SPECIAL_MODE_PREDS; ++i)
	      if (strcmp (pred_name, special_mode_pred_table[i]) == 0)
		{
		  special_mode_pred = 1;
		  break;
		}
	  }

	if (code == MATCH_OPERAND)
	  {
	    const char constraints0 = XSTR (pattern, 2)[0];

	    /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
	       don't use the MATCH_OPERAND constraint, only the predicate.
	       This is confusing to folks doing new ports, so help them
	       not make the mistake.  */
	    if (GET_CODE (insn) == DEFINE_EXPAND
		|| GET_CODE (insn) == DEFINE_SPLIT
		|| GET_CODE (insn) == DEFINE_PEEPHOLE2)
	      {
		if (constraints0)
		  message_with_line (pattern_lineno,
				     "warning: constraints not supported in %s",
				     rtx_name[GET_CODE (insn)]);
	      }

	    /* A MATCH_OPERAND that is a SET should have an output reload.  */
	    else if (set && constraints0)
	      {
		if (set_code == '+')
		  {
		    if (constraints0 == '+')
		      ;
		    /* If we've only got an output reload for this operand,
		       we'd better have a matching input operand.  */
		    else if (constraints0 == '='
			     && find_matching_operand (insn, XINT (pattern, 0)))
		      ;
		    else
		      {
			message_with_line (pattern_lineno,
					   "operand %d missing in-out reload",
					   XINT (pattern, 0));
			error_count++;
		      }
		  }
		else if (constraints0 != '=' && constraints0 != '+')
		  {
		    message_with_line (pattern_lineno,
				       "operand %d missing output reload",
				       XINT (pattern, 0));
		    error_count++;
		  }
	      }
	  }

	/* Allowing non-lvalues in destinations -- particularly CONST_INT --
	   while not likely to occur at runtime, results in less efficient
	   code from insn-recog.c.  */
	if (set
	    && pred_name[0] != '\0'
	    && allows_non_lvalue)
	  {
	    message_with_line (pattern_lineno,
			"warning: destination operand %d allows non-lvalue",
			XINT (pattern, 0));
	  }

	/* A modeless MATCH_OPERAND can be handy when we can
	   check for multiple modes in the c_test.  In most other cases,
	   it is a mistake.  Only DEFINE_INSN is eligible, since SPLIT
	   and PEEP2 can FAIL within the output pattern.  Exclude
	   address_operand, since its mode is related to the mode of
	   the memory not the operand.  Exclude the SET_DEST of a call
	   instruction, as that is a common idiom.  */

	if (GET_MODE (pattern) == VOIDmode
	    && code == MATCH_OPERAND
	    && GET_CODE (insn) == DEFINE_INSN
	    && allows_non_const
	    && ! special_mode_pred
	    && pred_name[0] != '\0'
	    && strcmp (pred_name, "address_operand") != 0
	    && strstr (c_test, "operands") == NULL
	    && ! (set
		  && GET_CODE (set) == SET
		  && GET_CODE (SET_SRC (set)) == CALL))
	  {
	    message_with_line (pattern_lineno,
			       "warning: operand %d missing mode?",
			       XINT (pattern, 0));
	  }
	return;
      }

    case SET:
      {
	enum machine_mode dmode, smode;
	rtx dest, src;

	dest = SET_DEST (pattern);
	src = SET_SRC (pattern);

	/* STRICT_LOW_PART is a wrapper.  Its argument is the real
	   destination, and it's mode should match the source.  */
	if (GET_CODE (dest) == STRICT_LOW_PART)
	  dest = XEXP (dest, 0);

	/* Find the referent for a DUP.  */

	if (GET_CODE (dest) == MATCH_DUP
	    || GET_CODE (dest) == MATCH_OP_DUP
	    || GET_CODE (dest) == MATCH_PAR_DUP)
	  dest = find_operand (insn, XINT (dest, 0), NULL);

	if (GET_CODE (src) == MATCH_DUP
	    || GET_CODE (src) == MATCH_OP_DUP
	    || GET_CODE (src) == MATCH_PAR_DUP)
	  src = find_operand (insn, XINT (src, 0), NULL);

	dmode = GET_MODE (dest);
	smode = GET_MODE (src);

	/* The mode of an ADDRESS_OPERAND is the mode of the memory
	   reference, not the mode of the address.  */
	if (GET_CODE (src) == MATCH_OPERAND
	    && ! strcmp (XSTR (src, 1), "address_operand"))
	  ;

        /* The operands of a SET must have the same mode unless one
	   is VOIDmode.  */
        else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
	  {
	    message_with_line (pattern_lineno,
			       "mode mismatch in set: %smode vs %smode",
			       GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
	    error_count++;
	  }

	/* If only one of the operands is VOIDmode, and PC or CC0 is
	   not involved, it's probably a mistake.  */
	else if (dmode != smode
		 && GET_CODE (dest) != PC
		 && GET_CODE (dest) != CC0
		 && GET_CODE (src) != PC
		 && GET_CODE (src) != CC0
		 && GET_CODE (src) != CONST_INT)
	  {
	    const char *which;
	    which = (dmode == VOIDmode ? "destination" : "source");
	    message_with_line (pattern_lineno,
			       "warning: %s missing a mode?", which);
	  }

	if (dest != SET_DEST (pattern))
	  validate_pattern (dest, insn, pattern, '=');
	validate_pattern (SET_DEST (pattern), insn, pattern, '=');
        validate_pattern (SET_SRC (pattern), insn, NULL_RTX, 0);
        return;
      }

    case CLOBBER:
      validate_pattern (SET_DEST (pattern), insn, pattern, '=');
      return;

    case ZERO_EXTRACT:
      validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
      validate_pattern (XEXP (pattern, 1), insn, NULL_RTX, 0);
      validate_pattern (XEXP (pattern, 2), insn, NULL_RTX, 0);
      return;

    case STRICT_LOW_PART:
      validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
      return;

    case LABEL_REF:
      if (GET_MODE (XEXP (pattern, 0)) != VOIDmode)
	{
	  message_with_line (pattern_lineno,
			     "operand to label_ref %smode not VOIDmode",
			     GET_MODE_NAME (GET_MODE (XEXP (pattern, 0))));
	  error_count++;
	}
      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':
	  validate_pattern (XEXP (pattern, i), insn, NULL_RTX, 0);
	  break;

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0);
	  break;

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

	default:
	  abort ();
	}
    }
}

/* Create a chain of nodes to verify that an rtl expression matches
   PATTERN.

   LAST is a pointer to the listhead in the previous node in the chain (or
   in the calling function, for the first node).

   POSITION is the string representing the current position in the insn.

   INSN_TYPE is the type of insn for which we are emitting code.

   A pointer to the final node in the chain is returned.  */

static struct decision *
add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
		 enum routine_type insn_type, int top)
{
  RTX_CODE code;
  struct decision *this, *sub;
  struct decision_test *test;
  struct decision_test **place;
  char *subpos;
  size_t i;
  const char *fmt;
  int depth = strlen (position);
  int len;
  enum machine_mode mode;

  if (depth > max_depth)
    max_depth = depth;

  subpos = xmalloc (depth + 2);
  strcpy (subpos, position);
  subpos[depth + 1] = 0;

  sub = this = new_decision (position, last);
  place = &this->tests;

 restart:
  mode = GET_MODE (pattern);
  code = GET_CODE (pattern);

  switch (code)
    {
    case PARALLEL:
      /* Toplevel peephole pattern.  */
      if (insn_type == PEEPHOLE2 && top)
	{
	  /* We don't need the node we just created -- unlink it.  */
	  last->first = last->last = NULL;

	  for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++)
	    {
	      /* Which insn we're looking at is represented by A-Z. We don't
	         ever use 'A', however; it is always implied.  */

	      subpos[depth] = (i > 0 ? 'A' + i : 0);
	      sub = add_to_sequence (XVECEXP (pattern, 0, i),
				     last, subpos, insn_type, 0);
	      last = &sub->success;
	    }
	  goto ret;
	}

      /* Else nothing special.  */
      break;

    case MATCH_PARALLEL:
      /* The explicit patterns within a match_parallel enforce a minimum
	 length on the vector.  The match_parallel predicate may allow
	 for more elements.  We do need to check for this minimum here
	 or the code generated to match the internals may reference data
	 beyond the end of the vector.  */
      test = new_decision_test (DT_veclen_ge, &place);
      test->u.veclen = XVECLEN (pattern, 2);
      /* Fall through.  */

    case MATCH_OPERAND:
    case MATCH_SCRATCH:
    case MATCH_OPERATOR:
    case MATCH_INSN:
      {
	const char *pred_name;
	RTX_CODE was_code = code;
	int allows_const_int = 1;

	if (code == MATCH_SCRATCH)
	  {
	    pred_name = "scratch_operand";
	    code = UNKNOWN;
	  }
	else
	  {
	    pred_name = XSTR (pattern, 1);
	    if (code == MATCH_PARALLEL)
	      code = PARALLEL;
	    else
	      code = UNKNOWN;
	  }

	if (pred_name[0] != 0)
	  {
	    test = new_decision_test (DT_pred, &place);
	    test->u.pred.name = pred_name;
	    test->u.pred.mode = mode;

	    /* See if we know about this predicate and save its number.
	       If we do, and it only accepts one code, note that fact.

	       If we know that the predicate does not allow CONST_INT,
	       we know that the only way the predicate can match is if
	       the modes match (here we use the kludge of relying on the
	       fact that "address_operand" accepts CONST_INT; otherwise,
	       it would have to be a special case), so we can test the
	       mode (but we need not).  This fact should considerably
	       simplify the generated code.  */

	    for (i = 0; i < NUM_KNOWN_PREDS; i++)
	      if (! strcmp (preds[i].name, pred_name))
		break;

	    if (i < NUM_KNOWN_PREDS)
	      {
		int j;

		test->u.pred.index = i;

		if (preds[i].codes[1] == 0 && code == UNKNOWN)
		  code = preds[i].codes[0];

		allows_const_int = 0;
		for (j = 0; preds[i].codes[j] != 0; j++)
		  if (preds[i].codes[j] == CONST_INT)
		    {
		      allows_const_int = 1;
		      break;
		    }
	      }
	    else
	      test->u.pred.index = -1;
	  }

	/* Can't enforce a mode if we allow const_int.  */
	if (allows_const_int)
	  mode = VOIDmode;

	/* Accept the operand, ie. record it in `operands'.  */
	test = new_decision_test (DT_accept_op, &place);
	test->u.opno = XINT (pattern, 0);

	if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL)
	  {
	    char base = (was_code == MATCH_OPERATOR ? '0' : 'a');
	    for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++)
	      {
		subpos[depth] = i + base;
		sub = add_to_sequence (XVECEXP (pattern, 2, i),
				       &sub->success, subpos, insn_type, 0);
	      }
	  }
	goto fini;
      }

    case MATCH_OP_DUP:
      code = UNKNOWN;

      test = new_decision_test (DT_dup, &place);
      test->u.dup = XINT (pattern, 0);

      test = new_decision_test (DT_accept_op, &place);
      test->u.opno = XINT (pattern, 0);

      for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
	{
	  subpos[depth] = i + '0';
	  sub = add_to_sequence (XVECEXP (pattern, 1, i),
				 &sub->success, subpos, insn_type, 0);
	}
      goto fini;

    case MATCH_DUP:
    case MATCH_PAR_DUP:
      code = UNKNOWN;

      test = new_decision_test (DT_dup, &place);
      test->u.dup = XINT (pattern, 0);
      goto fini;

    case ADDRESS:
      pattern = XEXP (pattern, 0);
      goto restart;

    default:
      break;
    }

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

  /* Do tests against the current node first.  */
  for (i = 0; i < (size_t) len; i++)
    {
      if (fmt[i] == 'i')
	{
	  if (i == 0)
	    {
	      test = new_decision_test (DT_elt_zero_int, &place);
	      test->u.intval = XINT (pattern, i);
	    }
	  else if (i == 1)
	    {
	      test = new_decision_test (DT_elt_one_int, &place);
	      test->u.intval = XINT (pattern, i);
	    }
	  else
	    abort ();
	}
      else if (fmt[i] == 'w')
	{
	  /* If this value actually fits in an int, we can use a switch
	     statement here, so indicate that.  */
	  enum decision_type type
	    = ((int) XWINT (pattern, i) == XWINT (pattern, i))
	      ? DT_elt_zero_wide_safe : DT_elt_zero_wide;

	  if (i != 0)
	    abort ();

	  test = new_decision_test (type, &place);
	  test->u.intval = XWINT (pattern, i);
	}
      else if (fmt[i] == 'E')
	{
	  if (i != 0)
	    abort ();

	  test = new_decision_test (DT_veclen, &place);
	  test->u.veclen = XVECLEN (pattern, i);
	}
    }

  /* Now test our sub-patterns.  */
  for (i = 0; i < (size_t) len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  subpos[depth] = '0' + i;
	  sub = add_to_sequence (XEXP (pattern, i), &sub->success,
				 subpos, insn_type, 0);
	  break;

	case 'E':
	  {
	    int j;
	    for (j = 0; j < XVECLEN (pattern, i); j++)
	      {
		subpos[depth] = 'a' + j;
		sub = add_to_sequence (XVECEXP (pattern, i, j),
				       &sub->success, subpos, insn_type, 0);
	      }
	    break;
	  }

	case 'i': case 'w':
	  /* Handled above.  */
	  break;
	case '0':
	  break;

	default:
	  abort ();
	}
    }

 fini:
  /* Insert nodes testing mode and code, if they're still relevant,
     before any of the nodes we may have added above.  */
  if (code != UNKNOWN)
    {
      place = &this->tests;
      test = new_decision_test (DT_code, &place);
      test->u.code = code;
    }

  if (mode != VOIDmode)
    {
      place = &this->tests;
      test = new_decision_test (DT_mode, &place);
      test->u.mode = mode;
    }

  /* If we didn't insert any tests or accept nodes, hork.  */
  if (this->tests == NULL)
    abort ();

 ret:
  free (subpos);
  return sub;
}

/* A subroutine of maybe_both_true; examines only one test.
   Returns > 0 for "definitely both true" and < 0 for "maybe both true".  */

static int
maybe_both_true_2 (struct decision_test *d1, struct decision_test *d2)
{
  if (d1->type == d2->type)
    {
      switch (d1->type)
	{
	case DT_mode:
	  return d1->u.mode == d2->u.mode;

	case DT_code:
	  return d1->u.code == d2->u.code;

	case DT_veclen:
	  return d1->u.veclen == d2->u.veclen;

	case DT_elt_zero_int:
	case DT_elt_one_int:
	case DT_elt_zero_wide:
	case DT_elt_zero_wide_safe:
	  return d1->u.intval == d2->u.intval;

	default:
	  break;
	}
    }

  /* If either has a predicate that we know something about, set
     things up so that D1 is the one that always has a known
     predicate.  Then see if they have any codes in common.  */

  if (d1->type == DT_pred || d2->type == DT_pred)
    {
      if (d2->type == DT_pred)
	{
	  struct decision_test *tmp;
	  tmp = d1, d1 = d2, d2 = tmp;
	}

      /* If D2 tests a mode, see if it matches D1.  */
      if (d1->u.pred.mode != VOIDmode)
	{
	  if (d2->type == DT_mode)
	    {
	      if (d1->u.pred.mode != d2->u.mode
		  /* The mode of an address_operand predicate is the
		     mode of the memory, not the operand.  It can only
		     be used for testing the predicate, so we must
		     ignore it here.  */
		  && strcmp (d1->u.pred.name, "address_operand") != 0)
		return 0;
	    }
	  /* Don't check two predicate modes here, because if both predicates
	     accept CONST_INT, then both can still be true even if the modes
	     are different.  If they don't accept CONST_INT, there will be a
	     separate DT_mode that will make maybe_both_true_1 return 0.  */
	}

      if (d1->u.pred.index >= 0)
	{
	  /* If D2 tests a code, see if it is in the list of valid
	     codes for D1's predicate.  */
	  if (d2->type == DT_code)
	    {
	      const RTX_CODE *c = &preds[d1->u.pred.index].codes[0];
	      while (*c != 0)
		{
		  if (*c == d2->u.code)
		    break;
		  ++c;
		}
	      if (*c == 0)
		return 0;
	    }

	  /* Otherwise see if the predicates have any codes in common.  */
	  else if (d2->type == DT_pred && d2->u.pred.index >= 0)
	    {
	      const RTX_CODE *c1 = &preds[d1->u.pred.index].codes[0];
	      int common = 0;

	      while (*c1 != 0 && !common)
		{
		  const RTX_CODE *c2 = &preds[d2->u.pred.index].codes[0];
		  while (*c2 != 0 && !common)
		    {
		      common = (*c1 == *c2);
		      ++c2;
		    }
		  ++c1;
		}

	      if (!common)
		return 0;
	    }
	}
    }

  /* Tests vs veclen may be known when strict equality is involved.  */
  if (d1->type == DT_veclen && d2->type == DT_veclen_ge)
    return d1->u.veclen >= d2->u.veclen;
  if (d1->type == DT_veclen_ge && d2->type == DT_veclen)
    return d2->u.veclen >= d1->u.veclen;

  return -1;
}

/* A subroutine of maybe_both_true; examines all the tests for a given node.
   Returns > 0 for "definitely both true" and < 0 for "maybe both true".  */

static int
maybe_both_true_1 (struct decision_test *d1, struct decision_test *d2)
{
  struct decision_test *t1, *t2;

  /* A match_operand with no predicate can match anything.  Recognize
     this by the existence of a lone DT_accept_op test.  */
  if (d1->type == DT_accept_op || d2->type == DT_accept_op)
    return 1;

  /* Eliminate pairs of tests while they can exactly match.  */
  while (d1 && d2 && d1->type == d2->type)
    {
      if (maybe_both_true_2 (d1, d2) == 0)
	return 0;
      d1 = d1->next, d2 = d2->next;
    }

  /* After that, consider all pairs.  */
  for (t1 = d1; t1 ; t1 = t1->next)
    for (t2 = d2; t2 ; t2 = t2->next)
      if (maybe_both_true_2 (t1, t2) == 0)
	return 0;

  return -1;
}

/* Return 0 if we can prove that there is no RTL that can match both
   D1 and D2.  Otherwise, return 1 (it may be that there is an RTL that
   can match both or just that we couldn't prove there wasn't such an RTL).

   TOPLEVEL is nonzero if we are to only look at the top level and not
   recursively descend.  */

static int
maybe_both_true (struct decision *d1, struct decision *d2,
		 int toplevel)
{
  struct decision *p1, *p2;
  int cmp;

  /* Don't compare strings on the different positions in insn.  Doing so
     is incorrect and results in false matches from constructs like

	[(set (subreg:HI (match_operand:SI "register_operand" "r") 0)
	      (subreg:HI (match_operand:SI "register_operand" "r") 0))]
     vs
	[(set (match_operand:HI "register_operand" "r")
	      (match_operand:HI "register_operand" "r"))]

     If we are presented with such, we are recursing through the remainder
     of a node's success nodes (from the loop at the end of this function).
     Skip forward until we come to a position that matches.

     Due to the way position strings are constructed, we know that iterating
     forward from the lexically lower position (e.g. "00") will run into
     the lexically higher position (e.g. "1") and not the other way around.
     This saves a bit of effort.  */

  cmp = strcmp (d1->position, d2->position);
  if (cmp != 0)
    {
      if (toplevel)
	abort ();

      /* If the d2->position was lexically lower, swap.  */
      if (cmp > 0)
	p1 = d1, d1 = d2, d2 = p1;

      if (d1->success.first == 0)
	return 1;
      for (p1 = d1->success.first; p1; p1 = p1->next)
	if (maybe_both_true (p1, d2, 0))
	  return 1;

      return 0;
    }

  /* Test the current level.  */
  cmp = maybe_both_true_1 (d1->tests, d2->tests);
  if (cmp >= 0)
    return cmp;

  /* We can't prove that D1 and D2 cannot both be true.  If we are only
     to check the top level, return 1.  Otherwise, see if we can prove
     that all choices in both successors are mutually exclusive.  If
     either does not have any successors, we can't prove they can't both
     be true.  */

  if (toplevel || d1->success.first == 0 || d2->success.first == 0)
    return 1;

  for (p1 = d1->success.first; p1; p1 = p1->next)
    for (p2 = d2->success.first; p2; p2 = p2->next)
      if (maybe_both_true (p1, p2, 0))
	return 1;

  return 0;
}

/* A subroutine of nodes_identical.  Examine two tests for equivalence.  */

static int
nodes_identical_1 (struct decision_test *d1, struct decision_test *d2)
{
  switch (d1->type)
    {
    case DT_mode:
      return d1->u.mode == d2->u.mode;

    case DT_code:
      return d1->u.code == d2->u.code;

    case DT_pred:
      return (d1->u.pred.mode == d2->u.pred.mode
	      && strcmp (d1->u.pred.name, d2->u.pred.name) == 0);

    case DT_c_test:
      return strcmp (d1->u.c_test, d2->u.c_test) == 0;

    case DT_veclen:
    case DT_veclen_ge:
      return d1->u.veclen == d2->u.veclen;

    case DT_dup:
      return d1->u.dup == d2->u.dup;

    case DT_elt_zero_int:
    case DT_elt_one_int:
    case DT_elt_zero_wide:
    case DT_elt_zero_wide_safe:
      return d1->u.intval == d2->u.intval;

    case DT_accept_op:
      return d1->u.opno == d2->u.opno;

    case DT_accept_insn:
      /* Differences will be handled in merge_accept_insn.  */
      return 1;

    default:
      abort ();
    }
}

/* True iff the two nodes are identical (on one level only).  Due
   to the way these lists are constructed, we shouldn't have to
   consider different orderings on the tests.  */

static int
nodes_identical (struct decision *d1, struct decision *d2)
{
  struct decision_test *t1, *t2;

  for (t1 = d1->tests, t2 = d2->tests; t1 && t2; t1 = t1->next, t2 = t2->next)
    {
      if (t1->type != t2->type)
	return 0;
      if (! nodes_identical_1 (t1, t2))
	return 0;
    }

  /* For success, they should now both be null.  */
  if (t1 != t2)
    return 0;

  /* Check that their subnodes are at the same position, as any one set
     of sibling decisions must be at the same position.  Allowing this
     requires complications to find_afterward and when change_state is
     invoked.  */
  if (d1->success.first
      && d2->success.first
      && strcmp (d1->success.first->position, d2->success.first->position))
    return 0;

  return 1;
}

/* A subroutine of merge_trees; given two nodes that have been declared
   identical, cope with two insn accept states.  If they differ in the
   number of clobbers, then the conflict was created by make_insn_sequence
   and we can drop the with-clobbers version on the floor.  If both
   nodes have no additional clobbers, we have found an ambiguity in the
   source machine description.  */

static void
merge_accept_insn (struct decision *oldd, struct decision *addd)
{
  struct decision_test *old, *add;

  for (old = oldd->tests; old; old = old->next)
    if (old->type == DT_accept_insn)
      break;
  if (old == NULL)
    return;

  for (add = addd->tests; add; add = add->next)
    if (add->type == DT_accept_insn)
      break;
  if (add == NULL)
    return;

  /* If one node is for a normal insn and the second is for the base
     insn with clobbers stripped off, the second node should be ignored.  */

  if (old->u.insn.num_clobbers_to_add == 0
      && add->u.insn.num_clobbers_to_add > 0)
    {
      /* Nothing to do here.  */
    }
  else if (old->u.insn.num_clobbers_to_add > 0
	   && add->u.insn.num_clobbers_to_add == 0)
    {
      /* In this case, replace OLD with ADD.  */
      old->u.insn = add->u.insn;
    }
  else
    {
      message_with_line (add->u.insn.lineno, "`%s' matches `%s'",
			 get_insn_name (add->u.insn.code_number),
			 get_insn_name (old->u.insn.code_number));
      message_with_line (old->u.insn.lineno, "previous definition of `%s'",
			 get_insn_name (old->u.insn.code_number));
      error_count++;
    }
}

/* Merge two decision trees OLDH and ADDH, modifying OLDH destructively.  */

static void
merge_trees (struct decision_head *oldh, struct decision_head *addh)
{
  struct decision *next, *add;

  if (addh->first == 0)
    return;
  if (oldh->first == 0)
    {
      *oldh = *addh;
      return;
    }

  /* Trying to merge bits at different positions isn't possible.  */
  if (strcmp (oldh->first->position, addh->first->position))
    abort ();

  for (add = addh->first; add ; add = next)
    {
      struct decision *old, *insert_before = NULL;

      next = add->next;

      /* The semantics of pattern matching state that the tests are
	 done in the order given in the MD file so that if an insn
	 matches two patterns, the first one will be used.  However,
	 in practice, most, if not all, patterns are unambiguous so
	 that their order is independent.  In that case, we can merge
	 identical tests and group all similar modes and codes together.

	 Scan starting from the end of OLDH until we reach a point
	 where we reach the head of the list or where we pass a
	 pattern that could also be true if NEW is true.  If we find
	 an identical pattern, we can merge them.  Also, record the
	 last node that tests the same code and mode and the last one
	 that tests just the same mode.

	 If we have no match, place NEW after the closest match we found.  */

      for (old = oldh->last; old; old = old->prev)
	{
	  if (nodes_identical (old, add))
	    {
	      merge_accept_insn (old, add);
	      merge_trees (&old->success, &add->success);
	      goto merged_nodes;
	    }

	  if (maybe_both_true (old, add, 0))
	    break;

	  /* Insert the nodes in DT test type order, which is roughly
	     how expensive/important the test is.  Given that the tests
	     are also ordered within the list, examining the first is
	     sufficient.  */
	  if ((int) add->tests->type < (int) old->tests->type)
	    insert_before = old;
	}

      if (insert_before == NULL)
	{
	  add->next = NULL;
	  add->prev = oldh->last;
	  oldh->last->next = add;
	  oldh->last = add;
	}
      else
	{
	  if ((add->prev = insert_before->prev) != NULL)
	    add->prev->next = add;
	  else
	    oldh->first = add;
	  add->next = insert_before;
	  insert_before->prev = add;
	}

    merged_nodes:;
    }
}

/* Walk the tree looking for sub-nodes that perform common tests.
   Factor out the common test into a new node.  This enables us
   (depending on the test type) to emit switch statements later.  */

static void
factor_tests (struct decision_head *head)
{
  struct decision *first, *next;

  for (first = head->first; first && first->next; first = next)
    {
      enum decision_type type;
      struct decision *new, *old_last;

      type = first->tests->type;
      next = first->next;

      /* Want at least two compatible sequential nodes.  */
      if (next->tests->type != type)
	continue;

      /* Don't want all node types, just those we can turn into
	 switch statements.  */
      if (type != DT_mode
	  && type != DT_code
	  && type != DT_veclen
	  && type != DT_elt_zero_int
	  && type != DT_elt_one_int
	  && type != DT_elt_zero_wide_safe)
	continue;

      /* If we'd been performing more than one test, create a new node
         below our first test.  */
      if (first->tests->next != NULL)
	{
	  new = new_decision (first->position, &first->success);
	  new->tests = first->tests->next;
	  first->tests->next = NULL;
	}

      /* Crop the node tree off after our first test.  */
      first->next = NULL;
      old_last = head->last;
      head->last = first;

      /* For each compatible test, adjust to perform only one test in
	 the top level node, then merge the node back into the tree.  */
      do
	{
	  struct decision_head h;

	  if (next->tests->next != NULL)
	    {
	      new = new_decision (next->position, &next->success);
	      new->tests = next->tests->next;
	      next->tests->next = NULL;
	    }
	  new = next;
	  next = next->next;
	  new->next = NULL;
	  h.first = h.last = new;

	  merge_trees (head, &h);
	}
      while (next && next->tests->type == type);

      /* After we run out of compatible tests, graft the remaining nodes
	 back onto the tree.  */
      if (next)
	{
	  next->prev = head->last;
	  head->last->next = next;
	  head->last = old_last;
	}
    }

  /* Recurse.  */
  for (first = head->first; first; first = first->next)
    factor_tests (&first->success);
}

/* After factoring, try to simplify the tests on any one node.
   Tests that are useful for switch statements are recognizable
   by having only a single test on a node -- we'll be manipulating
   nodes with multiple tests:

   If we have mode tests or code tests that are redundant with
   predicates, remove them.  */

static void
simplify_tests (struct decision_head *head)
{
  struct decision *tree;

  for (tree = head->first; tree; tree = tree->next)
    {
      struct decision_test *a, *b;

      a = tree->tests;
      b = a->next;
      if (b == NULL)
	continue;

      /* Find a predicate node.  */
      while (b && b->type != DT_pred)
	b = b->next;
      if (b)
	{
	  /* Due to how these tests are constructed, we don't even need
	     to check that the mode and code are compatible -- they were
	     generated from the predicate in the first place.  */
	  while (a->type == DT_mode || a->type == DT_code)
	    a = a->next;
	  tree->tests = a;
	}
    }

  /* Recurse.  */
  for (tree = head->first; tree; tree = tree->next)
    simplify_tests (&tree->success);
}

/* Count the number of subnodes of HEAD.  If the number is high enough,
   make the first node in HEAD start a separate subroutine in the C code
   that is generated.  */

static int
break_out_subroutines (struct decision_head *head, int initial)
{
  int size = 0;
  struct decision *sub;

  for (sub = head->first; sub; sub = sub->next)
    size += 1 + break_out_subroutines (&sub->success, 0);

  if (size > SUBROUTINE_THRESHOLD && ! initial)
    {
      head->first->subroutine_number = ++next_subroutine_number;
      size = 1;
    }
  return size;
}

/* For each node p, find the next alternative that might be true
   when p is true.  */

static void
find_afterward (struct decision_head *head, struct decision *real_afterward)
{
  struct decision *p, *q, *afterward;

  /* We can't propagate alternatives across subroutine boundaries.
     This is not incorrect, merely a minor optimization loss.  */

  p = head->first;
  afterward = (p->subroutine_number > 0 ? NULL : real_afterward);

  for ( ; p ; p = p->next)
    {
      /* Find the next node that might be true if this one fails.  */
      for (q = p->next; q ; q = q->next)
	if (maybe_both_true (p, q, 1))
	  break;

      /* If we reached the end of the list without finding one,
	 use the incoming afterward position.  */
      if (!q)
	q = afterward;
      p->afterward = q;
      if (q)
	q->need_label = 1;
    }

  /* Recurse.  */
  for (p = head->first; p ; p = p->next)
    if (p->success.first)
      find_afterward (&p->success, p->afterward);

  /* When we are generating a subroutine, record the real afterward
     position in the first node where write_tree can find it, and we
     can do the right thing at the subroutine call site.  */
  p = head->first;
  if (p->subroutine_number > 0)
    p->afterward = real_afterward;
}

/* Assuming that the state of argument is denoted by OLDPOS, take whatever
   actions are necessary to move to NEWPOS.  If we fail to move to the
   new state, branch to node AFTERWARD if nonzero, otherwise return.

   Failure to move to the new state can only occur if we are trying to
   match multiple insns and we try to step past the end of the stream.  */

static void
change_state (const char *oldpos, const char *newpos,
	      struct decision *afterward, const char *indent)
{
  int odepth = strlen (oldpos);
  int ndepth = strlen (newpos);
  int depth;
  int old_has_insn, new_has_insn;

  /* Pop up as many levels as necessary.  */
  for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth)
    continue;

  /* Hunt for the last [A-Z] in both strings.  */
  for (old_has_insn = odepth - 1; old_has_insn >= 0; --old_has_insn)
    if (ISUPPER (oldpos[old_has_insn]))
      break;
  for (new_has_insn = ndepth - 1; new_has_insn >= 0; --new_has_insn)
    if (ISUPPER (newpos[new_has_insn]))
      break;

  /* Go down to desired level.  */
  while (depth < ndepth)
    {
      /* It's a different insn from the first one.  */
      if (ISUPPER (newpos[depth]))
	{
	  /* We can only fail if we're moving down the tree.  */
	  if (old_has_insn >= 0 && oldpos[old_has_insn] >= newpos[depth])
	    {
	      printf ("%stem = peep2_next_insn (%d);\n",
		      indent, newpos[depth] - 'A');
	    }
	  else
	    {
	      printf ("%stem = peep2_next_insn (%d);\n",
		      indent, newpos[depth] - 'A');
	      printf ("%sif (tem == NULL_RTX)\n", indent);
	      if (afterward)
		printf ("%s  goto L%d;\n", indent, afterward->number);
	      else
		printf ("%s  goto ret0;\n", indent);
	    }
	  printf ("%sx%d = PATTERN (tem);\n", indent, depth + 1);
	}
      else if (ISLOWER (newpos[depth]))
	printf ("%sx%d = XVECEXP (x%d, 0, %d);\n",
		indent, depth + 1, depth, newpos[depth] - 'a');
      else
	printf ("%sx%d = XEXP (x%d, %c);\n",
		indent, depth + 1, depth, newpos[depth]);
      ++depth;
    }
}

/* Print the enumerator constant for CODE -- the upcase version of
   the name.  */

static void
print_code (enum rtx_code code)
{
  const char *p;
  for (p = GET_RTX_NAME (code); *p; p++)
    putchar (TOUPPER (*p));
}

/* Emit code to cross an afterward link -- change state and branch.  */

static void
write_afterward (struct decision *start, struct decision *afterward,
		 const char *indent)
{
  if (!afterward || start->subroutine_number > 0)
    printf("%sgoto ret0;\n", indent);
  else
    {
      change_state (start->position, afterward->position, NULL, indent);
      printf ("%sgoto L%d;\n", indent, afterward->number);
    }
}

/* Emit a HOST_WIDE_INT as an integer constant expression.  We need to take
   special care to avoid "decimal constant is so large that it is unsigned"
   warnings in the resulting code.  */

static void
print_host_wide_int (HOST_WIDE_INT val)
{
  HOST_WIDE_INT min = (unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1);
  if (val == min)
    printf ("(" HOST_WIDE_INT_PRINT_DEC_C "-1)", val + 1);
  else
    printf (HOST_WIDE_INT_PRINT_DEC_C, val);
}

/* Emit a switch statement, if possible, for an initial sequence of
   nodes at START.  Return the first node yet untested.  */

static struct decision *
write_switch (struct decision *start, int depth)
{
  struct decision *p = start;
  enum decision_type type = p->tests->type;
  struct decision *needs_label = NULL;

  /* If we have two or more nodes in sequence that test the same one
     thing, we may be able to use a switch statement.  */

  if (!p->next
      || p->tests->next
      || p->next->tests->type != type
      || p->next->tests->next
      || nodes_identical_1 (p->tests, p->next->tests))
    return p;

  /* DT_code is special in that we can do interesting things with
     known predicates at the same time.  */
  if (type == DT_code)
    {
      char codemap[NUM_RTX_CODE];
      struct decision *ret;
      RTX_CODE code;

      memset (codemap, 0, sizeof(codemap));

      printf ("  switch (GET_CODE (x%d))\n    {\n", depth);
      code = p->tests->u.code;
      do
	{
	  if (p != start && p->need_label && needs_label == NULL)
	    needs_label = p;

	  printf ("    case ");
	  print_code (code);
	  printf (":\n      goto L%d;\n", p->success.first->number);
	  p->success.first->need_label = 1;

	  codemap[code] = 1;
	  p = p->next;
	}
      while (p
	     && ! p->tests->next
	     && p->tests->type == DT_code
	     && ! codemap[code = p->tests->u.code]);

      /* If P is testing a predicate that we know about and we haven't
	 seen any of the codes that are valid for the predicate, we can
	 write a series of "case" statement, one for each possible code.
	 Since we are already in a switch, these redundant tests are very
	 cheap and will reduce the number of predicates called.  */

      /* Note that while we write out cases for these predicates here,
	 we don't actually write the test here, as it gets kinda messy.
	 It is trivial to leave this to later by telling our caller that
	 we only processed the CODE tests.  */
      if (needs_label != NULL)
	ret = needs_label;
      else
	ret = p;

      while (p && p->tests->type == DT_pred
	     && p->tests->u.pred.index >= 0)
	{
	  const RTX_CODE *c;

	  for (c = &preds[p->tests->u.pred.index].codes[0]; *c ; ++c)
	    if (codemap[(int) *c] != 0)
	      goto pred_done;

	  for (c = &preds[p->tests->u.pred.index].codes[0]; *c ; ++c)
	    {
	      printf ("    case ");
	      print_code (*c);
	      printf (":\n");
	      codemap[(int) *c] = 1;
	    }

	  printf ("      goto L%d;\n", p->number);
	  p->need_label = 1;
	  p = p->next;
	}

    pred_done:
      /* Make the default case skip the predicates we managed to match.  */

      printf ("    default:\n");
      if (p != ret)
	{
	  if (p)
	    {
	      printf ("      goto L%d;\n", p->number);
	      p->need_label = 1;
	    }
	  else
	    write_afterward (start, start->afterward, "      ");
	}
      else
	printf ("     break;\n");
      printf ("   }\n");

      return ret;
    }
  else if (type == DT_mode
	   || type == DT_veclen
	   || type == DT_elt_zero_int
	   || type == DT_elt_one_int
	   || type == DT_elt_zero_wide_safe)
    {
      const char *indent = "";

      /* We cast switch parameter to integer, so we must ensure that the value
	 fits.  */
      if (type == DT_elt_zero_wide_safe)
	{
	  indent = "  ";
	  printf("  if ((int) XWINT (x%d, 0) == XWINT (x%d, 0))\n", depth, depth);
	}
      printf ("%s  switch (", indent);
      switch (type)
	{
	case DT_mode:
	  printf ("GET_MODE (x%d)", depth);
	  break;
	case DT_veclen:
	  printf ("XVECLEN (x%d, 0)", depth);
	  break;
	case DT_elt_zero_int:
	  printf ("XINT (x%d, 0)", depth);
	  break;
	case DT_elt_one_int:
	  printf ("XINT (x%d, 1)", depth);
	  break;
	case DT_elt_zero_wide_safe:
	  /* Convert result of XWINT to int for portability since some C
	     compilers won't do it and some will.  */
	  printf ("(int) XWINT (x%d, 0)", depth);
	  break;
	default:
	  abort ();
	}
      printf (")\n%s    {\n", indent);

      do
	{
	  /* Merge trees will not unify identical nodes if their
	     sub-nodes are at different levels.  Thus we must check
	     for duplicate cases.  */
	  struct decision *q;
	  for (q = start; q != p; q = q->next)
	    if (nodes_identical_1 (p->tests, q->tests))
	      goto case_done;

	  if (p != start && p->need_label && needs_label == NULL)
	    needs_label = p;

	  printf ("%s    case ", indent);
	  switch (type)
	    {
	    case DT_mode:
	      printf ("%smode", GET_MODE_NAME (p->tests->u.mode));
	      break;
	    case DT_veclen:
	      printf ("%d", p->tests->u.veclen);
	      break;
	    case DT_elt_zero_int:
	    case DT_elt_one_int:
	    case DT_elt_zero_wide:
	    case DT_elt_zero_wide_safe:
	      print_host_wide_int (p->tests->u.intval);
	      break;
	    default:
	      abort ();
	    }
	  printf (":\n%s      goto L%d;\n", indent, p->success.first->number);
	  p->success.first->need_label = 1;

	  p = p->next;
	}
      while (p && p->tests->type == type && !p->tests->next);

    case_done:
      printf ("%s    default:\n%s      break;\n%s    }\n",
	      indent, indent, indent);

      return needs_label != NULL ? needs_label : p;
    }
  else
    {
      /* None of the other tests are amenable.  */
      return p;
    }
}

/* Emit code for one test.  */

static void
write_cond (struct decision_test *p, int depth,
	    enum routine_type subroutine_type)
{
  switch (p->type)
    {
    case DT_mode:
      printf ("GET_MODE (x%d) == %smode", depth, GET_MODE_NAME (p->u.mode));
      break;

    case DT_code:
      printf ("GET_CODE (x%d) == ", depth);
      print_code (p->u.code);
      break;

    case DT_veclen:
      printf ("XVECLEN (x%d, 0) == %d", depth, p->u.veclen);
      break;

    case DT_elt_zero_int:
      printf ("XINT (x%d, 0) == %d", depth, (int) p->u.intval);
      break;

    case DT_elt_one_int:
      printf ("XINT (x%d, 1) == %d", depth, (int) p->u.intval);
      break;

    case DT_elt_zero_wide:
    case DT_elt_zero_wide_safe:
      printf ("XWINT (x%d, 0) == ", depth);
      print_host_wide_int (p->u.intval);
      break;

    case DT_veclen_ge:
      printf ("XVECLEN (x%d, 0) >= %d", depth, p->u.veclen);
      break;

    case DT_dup:
      printf ("rtx_equal_p (x%d, operands[%d])", depth, p->u.dup);
      break;

    case DT_pred:
      printf ("%s (x%d, %smode)", p->u.pred.name, depth,
	      GET_MODE_NAME (p->u.pred.mode));
      break;

    case DT_c_test:
      printf ("(%s)", p->u.c_test);
      break;

    case DT_accept_insn:
      switch (subroutine_type)
	{
	case RECOG:
	  if (p->u.insn.num_clobbers_to_add == 0)
	    abort ();
	  printf ("pnum_clobbers != NULL");
	  break;

	default:
	  abort ();
	}
      break;

    default:
      abort ();
    }
}

/* Emit code for one action.  The previous tests have succeeded;
   TEST is the last of the chain.  In the normal case we simply
   perform a state change.  For the `accept' tests we must do more work.  */

static void
write_action (struct decision *p, struct decision_test *test,
	      int depth, int uncond, struct decision *success,
	      enum routine_type subroutine_type)
{
  const char *indent;
  int want_close = 0;

  if (uncond)
    indent = "  ";
  else if (test->type == DT_accept_op || test->type == DT_accept_insn)
    {
      fputs ("    {\n", stdout);
      indent = "      ";
      want_close = 1;
    }
  else
    indent = "    ";

  if (test->type == DT_accept_op)
    {
      printf("%soperands[%d] = x%d;\n", indent, test->u.opno, depth);

      /* Only allow DT_accept_insn to follow.  */
      if (test->next)
	{
	  test = test->next;
	  if (test->type != DT_accept_insn)
	    abort ();
	}
    }

  /* Sanity check that we're now at the end of the list of tests.  */
  if (test->next)
    abort ();

  if (test->type == DT_accept_insn)
    {
      switch (subroutine_type)
	{
	case RECOG:
	  if (test->u.insn.num_clobbers_to_add != 0)
	    printf ("%s*pnum_clobbers = %d;\n",
		    indent, test->u.insn.num_clobbers_to_add);
	  printf ("%sreturn %d;\n", indent, test->u.insn.code_number);
	  break;

	case SPLIT:
	  printf ("%sreturn gen_split_%d (operands);\n",
		  indent, test->u.insn.code_number);
	  break;

	case PEEPHOLE2:
	  {
	    int match_len = 0, i;

	    for (i = strlen (p->position) - 1; i >= 0; --i)
	      if (ISUPPER (p->position[i]))
		{
		  match_len = p->position[i] - 'A';
		  break;
		}
	    printf ("%s*_pmatch_len = %d;\n", indent, match_len);
	    printf ("%stem = gen_peephole2_%d (insn, operands);\n",
		    indent, test->u.insn.code_number);
	    printf ("%sif (tem != 0)\n%s  return tem;\n", indent, indent);
	  }
	  break;

	default:
	  abort ();
	}
    }
  else
    {
      printf("%sgoto L%d;\n", indent, success->number);
      success->need_label = 1;
    }

  if (want_close)
    fputs ("    }\n", stdout);
}

/* Return 1 if the test is always true and has no fallthru path.  Return -1
   if the test does have a fallthru path, but requires that the condition be
   terminated.  Otherwise return 0 for a normal test.  */
/* ??? is_unconditional is a stupid name for a tri-state function.  */

static int
is_unconditional (struct decision_test *t, enum routine_type subroutine_type)
{
  if (t->type == DT_accept_op)
    return 1;

  if (t->type == DT_accept_insn)
    {
      switch (subroutine_type)
	{
	case RECOG:
	  return (t->u.insn.num_clobbers_to_add == 0);
	case SPLIT:
	  return 1;
	case PEEPHOLE2:
	  return -1;
	default:
	  abort ();
	}
    }

  return 0;
}

/* Emit code for one node -- the conditional and the accompanying action.
   Return true if there is no fallthru path.  */

static int
write_node (struct decision *p, int depth,
	    enum routine_type subroutine_type)
{
  struct decision_test *test, *last_test;
  int uncond;

  last_test = test = p->tests;
  uncond = is_unconditional (test, subroutine_type);
  if (uncond == 0)
    {
      printf ("  if (");
      write_cond (test, depth, subroutine_type);

      while ((test = test->next) != NULL)
	{
	  int uncond2;

	  last_test = test;
	  uncond2 = is_unconditional (test, subroutine_type);
	  if (uncond2 != 0)
	    break;

	  printf ("\n      && ");
	  write_cond (test, depth, subroutine_type);
	}

      printf (")\n");
    }

  write_action (p, last_test, depth, uncond, p->success.first, subroutine_type);

  return uncond > 0;
}

/* Emit code for all of the sibling nodes of HEAD.  */

static void
write_tree_1 (struct decision_head *head, int depth,
	      enum routine_type subroutine_type)
{
  struct decision *p, *next;
  int uncond = 0;

  for (p = head->first; p ; p = next)
    {
      /* The label for the first element was printed in write_tree.  */
      if (p != head->first && p->need_label)
	OUTPUT_LABEL (" ", p->number);

      /* Attempt to write a switch statement for a whole sequence.  */
      next = write_switch (p, depth);
      if (p != next)
	uncond = 0;
      else
	{
	  /* Failed -- fall back and write one node.  */
	  uncond = write_node (p, depth, subroutine_type);
	  next = p->next;
	}
    }

  /* Finished with this chain.  Close a fallthru path by branching
     to the afterward node.  */
  if (! uncond)
    write_afterward (head->last, head->last->afterward, "  ");
}

/* Write out the decision tree starting at HEAD.  PREVPOS is the
   position at the node that branched to this node.  */

static void
write_tree (struct decision_head *head, const char *prevpos,
	    enum routine_type type, int initial)
{
  struct decision *p = head->first;

  putchar ('\n');
  if (p->need_label)
    OUTPUT_LABEL (" ", p->number);

  if (! initial && p->subroutine_number > 0)
    {
      static const char * const name_prefix[] = {
	  "recog", "split", "peephole2"
      };

      static const char * const call_suffix[] = {
	  ", pnum_clobbers", "", ", _pmatch_len"
      };

      /* This node has been broken out into a separate subroutine.
	 Call it, test the result, and branch accordingly.  */

      if (p->afterward)
	{
	  printf ("  tem = %s_%d (x0, insn%s);\n",
		  name_prefix[type], p->subroutine_number, call_suffix[type]);
	  if (IS_SPLIT (type))
	    printf ("  if (tem != 0)\n    return tem;\n");
	  else
	    printf ("  if (tem >= 0)\n    return tem;\n");

	  change_state (p->position, p->afterward->position, NULL, "  ");
	  printf ("  goto L%d;\n", p->afterward->number);
	}
      else
	{
	  printf ("  return %s_%d (x0, insn%s);\n",
		  name_prefix[type], p->subroutine_number, call_suffix[type]);
	}
    }
  else
    {
      int depth = strlen (p->position);

      change_state (prevpos, p->position, head->last->afterward, "  ");
      write_tree_1 (head, depth, type);

      for (p = head->first; p; p = p->next)
        if (p->success.first)
          write_tree (&p->success, p->position, type, 0);
    }
}

/* Write out a subroutine of type TYPE to do comparisons starting at
   node TREE.  */

static void
write_subroutine (struct decision_head *head, enum routine_type type)
{
  int subfunction = head->first ? head->first->subroutine_number : 0;
  const char *s_or_e;
  char extension[32];
  int i;

  s_or_e = subfunction ? "static " : "";

  if (subfunction)
    sprintf (extension, "_%d", subfunction);
  else if (type == RECOG)
    extension[0] = '\0';
  else
    strcpy (extension, "_insns");

  switch (type)
    {
    case RECOG:
      printf ("%sint\n\
recog%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n", s_or_e, extension);
      break;
    case SPLIT:
      printf ("%srtx\n\
split%s (rtx x0 ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
	      s_or_e, extension);
      break;
    case PEEPHOLE2:
      printf ("%srtx\n\
peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pmatch_len ATTRIBUTE_UNUSED)\n",
	      s_or_e, extension);
      break;
    }

  printf ("{\n  rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0];\n");
  for (i = 1; i <= max_depth; i++)
    printf ("  rtx x%d ATTRIBUTE_UNUSED;\n", i);

  printf ("  %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int");

  if (!subfunction)
    printf ("  recog_data.insn = NULL_RTX;\n");

  if (head->first)
    write_tree (head, "", type, 1);
  else
    printf ("  goto ret0;\n");

  printf (" ret0:\n  return %d;\n}\n\n", IS_SPLIT (type) ? 0 : -1);
}

/* In break_out_subroutines, we discovered the boundaries for the
   subroutines, but did not write them out.  Do so now.  */

static void
write_subroutines (struct decision_head *head, enum routine_type type)
{
  struct decision *p;

  for (p = head->first; p ; p = p->next)
    if (p->success.first)
      write_subroutines (&p->success, type);

  if (head->first->subroutine_number > 0)
    write_subroutine (head, type);
}

/* Begin the output file.  */

static void
write_header (void)
{
  puts ("\
/* Generated automatically by the program `genrecog' from the target\n\
   machine description file.  */\n\
\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
#include \"coretypes.h\"\n\
#include \"tm.h\"\n\
#include \"rtl.h\"\n\
#include \"tm_p.h\"\n\
#include \"function.h\"\n\
#include \"insn-config.h\"\n\
#include \"recog.h\"\n\
#include \"real.h\"\n\
#include \"output.h\"\n\
#include \"flags.h\"\n\
#include \"hard-reg-set.h\"\n\
#include \"resource.h\"\n\
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
\n");

  puts ("\n\
/* `recog' contains a decision tree that recognizes whether the rtx\n\
   X0 is a valid instruction.\n\
\n\
   recog returns -1 if the rtx is not valid.  If the rtx is valid, recog\n\
   returns a nonnegative number which is the insn code number for the\n\
   pattern that matched.  This is the same as the order in the machine\n\
   description of the entry that matched.  This number can be used as an\n\
   index into `insn_data' and other tables.\n");
  puts ("\
   The third argument to recog is an optional pointer to an int.  If\n\
   present, recog will accept a pattern if it matches except for missing\n\
   CLOBBER expressions at the end.  In that case, the value pointed to by\n\
   the optional pointer will be set to the number of CLOBBERs that need\n\
   to be added (it should be initialized to zero by the caller).  If it");
  puts ("\
   is set nonzero, the caller should allocate a PARALLEL of the\n\
   appropriate size, copy the initial entries, and call add_clobbers\n\
   (found in insn-emit.c) to fill in the CLOBBERs.\n\
");

  puts ("\n\
   The function split_insns returns 0 if the rtl could not\n\
   be split or the split rtl as an INSN list if it can be.\n\
\n\
   The function peephole2_insns returns 0 if the rtl could not\n\
   be matched. If there was a match, the new rtl is returned in an INSN list,\n\
   and LAST_INSN will point to the last recognized insn in the old sequence.\n\
*/\n\n");
}


/* Construct and return a sequence of decisions
   that will recognize INSN.

   TYPE says what type of routine we are recognizing (RECOG or SPLIT).  */

static struct decision_head
make_insn_sequence (rtx insn, enum routine_type type)
{
  rtx x;
  const char *c_test = XSTR (insn, type == RECOG ? 2 : 1);
  int truth = maybe_eval_c_test (c_test);
  struct decision *last;
  struct decision_test *test, **place;
  struct decision_head head;
  char c_test_pos[2];

  /* We should never see an insn whose C test is false at compile time.  */
  if (truth == 0)
    abort ();

  record_insn_name (next_insn_code, (type == RECOG ? XSTR (insn, 0) : NULL));

  c_test_pos[0] = '\0';
  if (type == PEEPHOLE2)
    {
      int i, j;

      /* peephole2 gets special treatment:
	 - X always gets an outer parallel even if it's only one entry
	 - we remove all traces of outer-level match_scratch and match_dup
           expressions here.  */
      x = rtx_alloc (PARALLEL);
      PUT_MODE (x, VOIDmode);
      XVEC (x, 0) = rtvec_alloc (XVECLEN (insn, 0));
      for (i = j = 0; i < XVECLEN (insn, 0); i++)
	{
	  rtx tmp = XVECEXP (insn, 0, i);
	  if (GET_CODE (tmp) != MATCH_SCRATCH && GET_CODE (tmp) != MATCH_DUP)
	    {
	      XVECEXP (x, 0, j) = tmp;
	      j++;
	    }
	}
      XVECLEN (x, 0) = j;

      c_test_pos[0] = 'A' + j - 1;
      c_test_pos[1] = '\0';
    }
  else if (XVECLEN (insn, type == RECOG) == 1)
    x = XVECEXP (insn, type == RECOG, 0);
  else
    {
      x = rtx_alloc (PARALLEL);
      XVEC (x, 0) = XVEC (insn, type == RECOG);
      PUT_MODE (x, VOIDmode);
    }

  validate_pattern (x, insn, NULL_RTX, 0);

  memset(&head, 0, sizeof(head));
  last = add_to_sequence (x, &head, "", type, 1);

  /* Find the end of the test chain on the last node.  */
  for (test = last->tests; test->next; test = test->next)
    continue;
  place = &test->next;

  /* Skip the C test if it's known to be true at compile time.  */
  if (truth == -1)
    {
      /* Need a new node if we have another test to add.  */
      if (test->type == DT_accept_op)
	{
	  last = new_decision (c_test_pos, &last->success);
	  place = &last->tests;
	}
      test = new_decision_test (DT_c_test, &place);
      test->u.c_test = c_test;
    }

  test = new_decision_test (DT_accept_insn, &place);
  test->u.insn.code_number = next_insn_code;
  test->u.insn.lineno = pattern_lineno;
  test->u.insn.num_clobbers_to_add = 0;

  switch (type)
    {
    case RECOG:
      /* If this is a DEFINE_INSN and X is a PARALLEL, see if it ends
	 with a group of CLOBBERs of (hard) registers or MATCH_SCRATCHes.
	 If so, set up to recognize the pattern without these CLOBBERs.  */

      if (GET_CODE (x) == PARALLEL)
	{
	  int i;

	  /* Find the last non-clobber in the parallel.  */
	  for (i = XVECLEN (x, 0); i > 0; i--)
	    {
	      rtx y = XVECEXP (x, 0, i - 1);
	      if (GET_CODE (y) != CLOBBER
		  || (GET_CODE (XEXP (y, 0)) != REG
		      && GET_CODE (XEXP (y, 0)) != MATCH_SCRATCH))
		break;
	    }

	  if (i != XVECLEN (x, 0))
	    {
	      rtx new;
	      struct decision_head clobber_head;

	      /* Build a similar insn without the clobbers.  */
	      if (i == 1)
		new = XVECEXP (x, 0, 0);
	      else
		{
		  int j;

		  new = rtx_alloc (PARALLEL);
		  XVEC (new, 0) = rtvec_alloc (i);
		  for (j = i - 1; j >= 0; j--)
		    XVECEXP (new, 0, j) = XVECEXP (x, 0, j);
		}

	      /* Recognize it.  */
	      memset (&clobber_head, 0, sizeof(clobber_head));
	      last = add_to_sequence (new, &clobber_head, "", type, 1);

	      /* Find the end of the test chain on the last node.  */
	      for (test = last->tests; test->next; test = test->next)
		continue;

	      /* We definitely have a new test to add -- create a new
		 node if needed.  */
	      place = &test->next;
	      if (test->type == DT_accept_op)
		{
		  last = new_decision ("", &last->success);
		  place = &last->tests;
		}

	      /* Skip the C test if it's known to be true at compile
                 time.  */
	      if (truth == -1)
		{
		  test = new_decision_test (DT_c_test, &place);
		  test->u.c_test = c_test;
		}

	      test = new_decision_test (DT_accept_insn, &place);
	      test->u.insn.code_number = next_insn_code;
	      test->u.insn.lineno = pattern_lineno;
	      test->u.insn.num_clobbers_to_add = XVECLEN (x, 0) - i;

	      merge_trees (&head, &clobber_head);
	    }
	}
      break;

    case SPLIT:
      /* Define the subroutine we will call below and emit in genemit.  */
      printf ("extern rtx gen_split_%d (rtx *);\n", next_insn_code);
      break;

    case PEEPHOLE2:
      /* Define the subroutine we will call below and emit in genemit.  */
      printf ("extern rtx gen_peephole2_%d (rtx, rtx *);\n",
	      next_insn_code);
      break;
    }

  return head;
}

static void
process_tree (struct decision_head *head, enum routine_type subroutine_type)
{
  if (head->first == NULL)
    {
      /* We can elide peephole2_insns, but not recog or split_insns.  */
      if (subroutine_type == PEEPHOLE2)
	return;
    }
  else
    {
      factor_tests (head);

      next_subroutine_number = 0;
      break_out_subroutines (head, 1);
      find_afterward (head, NULL);

      /* We run this after find_afterward, because find_afterward needs
	 the redundant DT_mode tests on predicates to determine whether
	 two tests can both be true or not.  */
      simplify_tests(head);

      write_subroutines (head, subroutine_type);
    }

  write_subroutine (head, subroutine_type);
}

extern int main (int, char **);

int
main (int argc, char **argv)
{
  rtx desc;
  struct decision_head recog_tree, split_tree, peephole2_tree, h;

  progname = "genrecog";

  memset (&recog_tree, 0, sizeof recog_tree);
  memset (&split_tree, 0, sizeof split_tree);
  memset (&peephole2_tree, 0, sizeof peephole2_tree);

  if (argc <= 1)
    fatal ("no input file name");

  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
    return (FATAL_EXIT_CODE);

  next_insn_code = 0;
  next_index = 0;

  write_header ();

  /* Read the machine description.  */

  while (1)
    {
      desc = read_md_rtx (&pattern_lineno, &next_insn_code);
      if (desc == NULL)
	break;

      if (GET_CODE (desc) == DEFINE_INSN)
	{
	  h = make_insn_sequence (desc, RECOG);
	  merge_trees (&recog_tree, &h);
	}
      else if (GET_CODE (desc) == DEFINE_SPLIT)
	{
	  h = make_insn_sequence (desc, SPLIT);
	  merge_trees (&split_tree, &h);
	}
      else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
	{
	  h = make_insn_sequence (desc, PEEPHOLE2);
	  merge_trees (&peephole2_tree, &h);
	}

      next_index++;
    }

  if (error_count)
    return FATAL_EXIT_CODE;

  puts ("\n\n");

  process_tree (&recog_tree, RECOG);
  process_tree (&split_tree, SPLIT);
  process_tree (&peephole2_tree, PEEPHOLE2);

  fflush (stdout);
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}

/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
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;

  if (insn_name_ptr_size <= code)
    {
      int new_size;
      new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
      insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * 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 = xmalloc (strlen (last_real_name) + 10);
      sprintf (new, "%s+%d", last_real_name, code - last_real_code);
    }
  else
    {
      last_real_name = new = xstrdup (name);
      last_real_code = code;
    }

  insn_name_ptr[code] = new;
}

static void
debug_decision_2 (struct decision_test *test)
{
  switch (test->type)
    {
    case DT_mode:
      fprintf (stderr, "mode=%s", GET_MODE_NAME (test->u.mode));
      break;
    case DT_code:
      fprintf (stderr, "code=%s", GET_RTX_NAME (test->u.code));
      break;
    case DT_veclen:
      fprintf (stderr, "veclen=%d", test->u.veclen);
      break;
    case DT_elt_zero_int:
      fprintf (stderr, "elt0_i=%d", (int) test->u.intval);
      break;
    case DT_elt_one_int:
      fprintf (stderr, "elt1_i=%d", (int) test->u.intval);
      break;
    case DT_elt_zero_wide:
      fprintf (stderr, "elt0_w=" HOST_WIDE_INT_PRINT_DEC, test->u.intval);
      break;
    case DT_elt_zero_wide_safe:
      fprintf (stderr, "elt0_ws=" HOST_WIDE_INT_PRINT_DEC, test->u.intval);
      break;
    case DT_veclen_ge:
      fprintf (stderr, "veclen>=%d", test->u.veclen);
      break;
    case DT_dup:
      fprintf (stderr, "dup=%d", test->u.dup);
      break;
    case DT_pred:
      fprintf (stderr, "pred=(%s,%s)",
	       test->u.pred.name, GET_MODE_NAME(test->u.pred.mode));
      break;
    case DT_c_test:
      {
	char sub[16+4];
	strncpy (sub, test->u.c_test, sizeof(sub));
	memcpy (sub+16, "...", 4);
	fprintf (stderr, "c_test=\"%s\"", sub);
      }
      break;
    case DT_accept_op:
      fprintf (stderr, "A_op=%d", test->u.opno);
      break;
    case DT_accept_insn:
      fprintf (stderr, "A_insn=(%d,%d)",
	       test->u.insn.code_number, test->u.insn.num_clobbers_to_add);
      break;

    default:
      abort ();
    }
}

static void
debug_decision_1 (struct decision *d, int indent)
{
  int i;
  struct decision_test *test;

  if (d == NULL)
    {
      for (i = 0; i < indent; ++i)
	putc (' ', stderr);
      fputs ("(nil)\n", stderr);
      return;
    }

  for (i = 0; i < indent; ++i)
    putc (' ', stderr);

  putc ('{', stderr);
  test = d->tests;
  if (test)
    {
      debug_decision_2 (test);
      while ((test = test->next) != NULL)
	{
	  fputs (" + ", stderr);
	  debug_decision_2 (test);
	}
    }
  fprintf (stderr, "} %d n %d a %d\n", d->number,
	   (d->next ? d->next->number : -1),
	   (d->afterward ? d->afterward->number : -1));
}

static void
debug_decision_0 (struct decision *d, int indent, int maxdepth)
{
  struct decision *n;
  int i;

  if (maxdepth < 0)
    return;
  if (d == NULL)
    {
      for (i = 0; i < indent; ++i)
	putc (' ', stderr);
      fputs ("(nil)\n", stderr);
      return;
    }

  debug_decision_1 (d, indent);
  for (n = d->success.first; n ; n = n->next)
    debug_decision_0 (n, indent + 2, maxdepth - 1);
}

void
debug_decision (struct decision *d)
{
  debug_decision_0 (d, 0, 1000000);
}

void
debug_decision_list (struct decision *d)
{
  while (d)
    {
      debug_decision_0 (d, 0, 0);
      d = d->next;
    }
}
