Home | History | Annotate | Line # | Download | only in gcc
gensupport.cc revision 1.1
      1 /* Support routines for the various generation passes.
      2    Copyright (C) 2000-2022 Free Software Foundation, Inc.
      3 
      4    This file is part of GCC.
      5 
      6    GCC is free software; you can redistribute it and/or modify it
      7    under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    GCC is distributed in the hope that it will be useful, but WITHOUT
     12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14    License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with GCC; see the file COPYING3.  If not see
     18    <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "bconfig.h"
     21 #include "system.h"
     22 #include "coretypes.h"
     23 #include "tm.h"
     24 #include "rtl.h"
     25 #include "obstack.h"
     26 #include "errors.h"
     27 #include "read-md.h"
     28 #include "gensupport.h"
     29 #include "vec.h"
     30 
     31 #define MAX_OPERANDS 40
     32 
     33 static rtx operand_data[MAX_OPERANDS];
     34 static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
     35 static char used_operands_numbers[MAX_OPERANDS];
     36 
     37 
     38 /* In case some macros used by files we include need it, define this here.  */
     39 int target_flags;
     40 
     41 int insn_elision = 1;
     42 
     43 static struct obstack obstack;
     44 struct obstack *rtl_obstack = &obstack;
     45 
     46 /* Counter for named patterns and INSN_CODEs.  */
     47 static int insn_sequence_num;
     48 
     49 /* Counter for define_splits.  */
     50 static int split_sequence_num;
     51 
     52 /* Counter for define_peephole2s.  */
     53 static int peephole2_sequence_num;
     54 
     55 static int predicable_default;
     56 static const char *predicable_true;
     57 static const char *predicable_false;
     58 
     59 static const char *subst_true = "yes";
     60 static const char *subst_false = "no";
     61 
     62 static htab_t condition_table;
     63 
     64 /* We initially queue all patterns, process the define_insn,
     65    define_cond_exec and define_subst patterns, then return
     66    them one at a time.  */
     67 
     68 class queue_elem
     69 {
     70 public:
     71   rtx data;
     72   file_location loc;
     73   class queue_elem *next;
     74   /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT or
     75      DEFINE_INSN_AND_REWRITE, SPLIT points to the generated DEFINE_SPLIT.  */
     76   class queue_elem *split;
     77 };
     78 
     79 #define MNEMONIC_ATTR_NAME "mnemonic"
     80 #define MNEMONIC_HTAB_SIZE 1024
     81 
     82 static class queue_elem *define_attr_queue;
     83 static class queue_elem **define_attr_tail = &define_attr_queue;
     84 static class queue_elem *define_pred_queue;
     85 static class queue_elem **define_pred_tail = &define_pred_queue;
     86 static class queue_elem *define_insn_queue;
     87 static class queue_elem **define_insn_tail = &define_insn_queue;
     88 static class queue_elem *define_cond_exec_queue;
     89 static class queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
     90 static class queue_elem *define_subst_queue;
     91 static class queue_elem **define_subst_tail = &define_subst_queue;
     92 static class queue_elem *other_queue;
     93 static class queue_elem **other_tail = &other_queue;
     94 static class queue_elem *define_subst_attr_queue;
     95 static class queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
     96 
     97 /* Mapping from DEFINE_* rtxes to their location in the source file.  */
     98 static hash_map <rtx, file_location> *rtx_locs;
     99 
    100 static void remove_constraints (rtx);
    101 
    102 static int is_predicable (class queue_elem *);
    103 static void identify_predicable_attribute (void);
    104 static int n_alternatives (const char *);
    105 static void collect_insn_data (rtx, int *, int *);
    106 static const char *alter_test_for_insn (class queue_elem *,
    107 					class queue_elem *);
    108 static char *shift_output_template (char *, const char *, int);
    109 static const char *alter_output_for_insn (class queue_elem *,
    110 					  class queue_elem *,
    111 					  int, int);
    112 static void process_one_cond_exec (class queue_elem *);
    113 static void process_define_cond_exec (void);
    114 static void init_predicate_table (void);
    115 static void record_insn_name (int, const char *);
    116 
    117 static bool has_subst_attribute (class queue_elem *, class queue_elem *);
    118 static const char * alter_output_for_subst_insn (rtx, int);
    119 static void alter_attrs_for_subst_insn (class queue_elem *, int);
    120 static void process_substs_on_one_elem (class queue_elem *,
    121 					class queue_elem *);
    122 static rtx subst_dup (rtx, int, int);
    123 static void process_define_subst (void);
    124 
    125 static const char * duplicate_alternatives (const char *, int);
    126 static const char * duplicate_each_alternative (const char * str, int n_dup);
    127 
    128 typedef const char * (*constraints_handler_t) (const char *, int);
    129 static rtx alter_constraints (rtx, int, constraints_handler_t);
    130 static rtx adjust_operands_numbers (rtx);
    131 static rtx replace_duplicating_operands_in_pattern (rtx);
    132 
    133 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
    135    the gensupport programs.  */
    136 
    137 rtx
    138 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
    139 		   HOST_WIDE_INT arg)
    140 {
    141   rtx rt = rtx_alloc (CONST_INT);
    142 
    143   XWINT (rt, 0) = arg;
    144   return rt;
    145 }
    146 
    147 /* Return the rtx pattern specified by the list of rtxes in a
    148    define_insn or define_split.  */
    149 
    150 rtx
    151 add_implicit_parallel (rtvec vec)
    152 {
    153   if (GET_NUM_ELEM (vec) == 1)
    154     return RTVEC_ELT (vec, 0);
    155   else
    156     {
    157       rtx pattern = rtx_alloc (PARALLEL);
    158       XVEC (pattern, 0) = vec;
    159       return pattern;
    160     }
    161 }
    162 
    163 /* Predicate handling.
    165 
    166    We construct from the machine description a table mapping each
    167    predicate to a list of the rtl codes it can possibly match.  The
    168    function 'maybe_both_true' uses it to deduce that there are no
    169    expressions that can be matches by certain pairs of tree nodes.
    170    Also, if a predicate can match only one code, we can hardwire that
    171    code into the node testing the predicate.
    172 
    173    Some predicates are flagged as special.  validate_pattern will not
    174    warn about modeless match_operand expressions if they have a
    175    special predicate.  Predicates that allow only constants are also
    176    treated as special, for this purpose.
    177 
    178    validate_pattern will warn about predicates that allow non-lvalues
    179    when they appear in destination operands.
    180 
    181    Calculating the set of rtx codes that can possibly be accepted by a
    182    predicate expression EXP requires a three-state logic: any given
    183    subexpression may definitively accept a code C (Y), definitively
    184    reject a code C (N), or may have an indeterminate effect (I).  N
    185    and I is N; Y or I is Y; Y and I, N or I are both I.  Here are full
    186    truth tables.
    187 
    188      a b  a&b  a|b
    189      Y Y   Y    Y
    190      N Y   N    Y
    191      N N   N    N
    192      I Y   I    Y
    193      I N   N    I
    194      I I   I    I
    195 
    196    We represent Y with 1, N with 0, I with 2.  If any code is left in
    197    an I state by the complete expression, we must assume that that
    198    code can be accepted.  */
    199 
    200 #define N 0
    201 #define Y 1
    202 #define I 2
    203 
    204 #define TRISTATE_AND(a,b)			\
    205   ((a) == I ? ((b) == N ? N : I) :		\
    206    (b) == I ? ((a) == N ? N : I) :		\
    207    (a) && (b))
    208 
    209 #define TRISTATE_OR(a,b)			\
    210   ((a) == I ? ((b) == Y ? Y : I) :		\
    211    (b) == I ? ((a) == Y ? Y : I) :		\
    212    (a) || (b))
    213 
    214 #define TRISTATE_NOT(a)				\
    215   ((a) == I ? I : !(a))
    216 
    217 /* 0 means no warning about that code yet, 1 means warned.  */
    218 static char did_you_mean_codes[NUM_RTX_CODE];
    219 
    220 /* Recursively calculate the set of rtx codes accepted by the
    221    predicate expression EXP, writing the result to CODES.  LOC is
    222    the .md file location of the directive containing EXP.  */
    223 
    224 void
    225 compute_test_codes (rtx exp, file_location loc, char *codes)
    226 {
    227   char op0_codes[NUM_RTX_CODE];
    228   char op1_codes[NUM_RTX_CODE];
    229   char op2_codes[NUM_RTX_CODE];
    230   int i;
    231 
    232   switch (GET_CODE (exp))
    233     {
    234     case AND:
    235       compute_test_codes (XEXP (exp, 0), loc, op0_codes);
    236       compute_test_codes (XEXP (exp, 1), loc, op1_codes);
    237       for (i = 0; i < NUM_RTX_CODE; i++)
    238 	codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
    239       break;
    240 
    241     case IOR:
    242       compute_test_codes (XEXP (exp, 0), loc, op0_codes);
    243       compute_test_codes (XEXP (exp, 1), loc, op1_codes);
    244       for (i = 0; i < NUM_RTX_CODE; i++)
    245 	codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
    246       break;
    247     case NOT:
    248       compute_test_codes (XEXP (exp, 0), loc, op0_codes);
    249       for (i = 0; i < NUM_RTX_CODE; i++)
    250 	codes[i] = TRISTATE_NOT (op0_codes[i]);
    251       break;
    252 
    253     case IF_THEN_ELSE:
    254       /* a ? b : c  accepts the same codes as (a & b) | (!a & c).  */
    255       compute_test_codes (XEXP (exp, 0), loc, op0_codes);
    256       compute_test_codes (XEXP (exp, 1), loc, op1_codes);
    257       compute_test_codes (XEXP (exp, 2), loc, op2_codes);
    258       for (i = 0; i < NUM_RTX_CODE; i++)
    259 	codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
    260 				TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
    261 					      op2_codes[i]));
    262       break;
    263 
    264     case MATCH_CODE:
    265       /* MATCH_CODE allows a specified list of codes.  However, if it
    266 	 does not apply to the top level of the expression, it does not
    267 	 constrain the set of codes for the top level.  */
    268       if (XSTR (exp, 1)[0] != '\0')
    269 	{
    270 	  memset (codes, Y, NUM_RTX_CODE);
    271 	  break;
    272 	}
    273 
    274       memset (codes, N, NUM_RTX_CODE);
    275       {
    276 	const char *next_code = XSTR (exp, 0);
    277 	const char *code;
    278 
    279 	if (*next_code == '\0')
    280 	  {
    281 	    error_at (loc, "empty match_code expression");
    282 	    break;
    283 	  }
    284 
    285 	while ((code = scan_comma_elt (&next_code)) != 0)
    286 	  {
    287 	    size_t n = next_code - code;
    288 	    int found_it = 0;
    289 
    290 	    for (i = 0; i < NUM_RTX_CODE; i++)
    291 	      if (!strncmp (code, GET_RTX_NAME (i), n)
    292 		  && GET_RTX_NAME (i)[n] == '\0')
    293 		{
    294 		  codes[i] = Y;
    295 		  found_it = 1;
    296 		  break;
    297 		}
    298 	    if (!found_it)
    299 	      {
    300 		error_at (loc, "match_code \"%.*s\" matches nothing",
    301 			  (int) n, code);
    302 		for (i = 0; i < NUM_RTX_CODE; i++)
    303 		  if (!strncasecmp (code, GET_RTX_NAME (i), n)
    304 		      && GET_RTX_NAME (i)[n] == '\0'
    305 		      && !did_you_mean_codes[i])
    306 		    {
    307 		      did_you_mean_codes[i] = 1;
    308 		      message_at (loc, "(did you mean \"%s\"?)",
    309 				  GET_RTX_NAME (i));
    310 		    }
    311 	      }
    312 	  }
    313       }
    314       break;
    315 
    316     case MATCH_OPERAND:
    317       /* MATCH_OPERAND disallows the set of codes that the named predicate
    318 	 disallows, and is indeterminate for the codes that it does allow.  */
    319       {
    320 	struct pred_data *p = lookup_predicate (XSTR (exp, 1));
    321 	if (!p)
    322 	  {
    323 	    error_at (loc, "reference to unknown predicate '%s'",
    324 		      XSTR (exp, 1));
    325 	    break;
    326 	  }
    327 	for (i = 0; i < NUM_RTX_CODE; i++)
    328 	  codes[i] = p->codes[i] ? I : N;
    329       }
    330       break;
    331 
    332 
    333     case MATCH_TEST:
    334       /* (match_test WHATEVER) is completely indeterminate.  */
    335       memset (codes, I, NUM_RTX_CODE);
    336       break;
    337 
    338     default:
    339       error_at (loc, "'%s' cannot be used in predicates or constraints",
    340 		GET_RTX_NAME (GET_CODE (exp)));
    341       memset (codes, I, NUM_RTX_CODE);
    342       break;
    343     }
    344 }
    345 
    346 #undef TRISTATE_OR
    347 #undef TRISTATE_AND
    348 #undef TRISTATE_NOT
    349 
    350 /* Return true if NAME is a valid predicate name.  */
    351 
    352 static bool
    353 valid_predicate_name_p (const char *name)
    354 {
    355   const char *p;
    356 
    357   if (!ISALPHA (name[0]) && name[0] != '_')
    358     return false;
    359   for (p = name + 1; *p; p++)
    360     if (!ISALNUM (*p) && *p != '_')
    361       return false;
    362   return true;
    363 }
    364 
    365 /* Process define_predicate directive DESC, which appears at location LOC.
    366    Compute the set of codes that can be matched, and record this as a known
    367    predicate.  */
    368 
    369 static void
    370 process_define_predicate (rtx desc, file_location loc)
    371 {
    372   struct pred_data *pred;
    373   char codes[NUM_RTX_CODE];
    374   int i;
    375 
    376   if (!valid_predicate_name_p (XSTR (desc, 0)))
    377     {
    378       error_at (loc, "%s: predicate name must be a valid C function name",
    379 		XSTR (desc, 0));
    380       return;
    381     }
    382 
    383   pred = XCNEW (struct pred_data);
    384   pred->name = XSTR (desc, 0);
    385   pred->exp = XEXP (desc, 1);
    386   pred->c_block = XSTR (desc, 2);
    387   if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
    388     pred->special = true;
    389 
    390   compute_test_codes (XEXP (desc, 1), loc, codes);
    391 
    392   for (i = 0; i < NUM_RTX_CODE; i++)
    393     if (codes[i] != N)
    394       add_predicate_code (pred, (enum rtx_code) i);
    395 
    396   add_predicate (pred);
    397 }
    398 #undef I
    399 #undef N
    400 #undef Y
    401 
    402 /* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
    404    element.  */
    405 
    406 static class queue_elem *
    407 queue_pattern (rtx pattern, class queue_elem ***list_tail,
    408 	       file_location loc)
    409 {
    410   class queue_elem *e = XNEW (class queue_elem);
    411   e->data = pattern;
    412   e->loc = loc;
    413   e->next = NULL;
    414   e->split = NULL;
    415   **list_tail = e;
    416   *list_tail = &e->next;
    417   return e;
    418 }
    419 
    420 /* Remove element ELEM from QUEUE.  */
    421 static void
    422 remove_from_queue (class queue_elem *elem, class queue_elem **queue)
    423 {
    424   class queue_elem *prev, *e;
    425   prev = NULL;
    426   for (e = *queue; e ; e = e->next)
    427     {
    428       if (e == elem)
    429 	break;
    430       prev = e;
    431     }
    432   if (e == NULL)
    433     return;
    434 
    435   if (prev)
    436     prev->next = elem->next;
    437   else
    438     *queue = elem->next;
    439 }
    440 
    441 /* Build a define_attr for an binary attribute with name NAME and
    442    possible values "yes" and "no", and queue it.  */
    443 static void
    444 add_define_attr (const char *name)
    445 {
    446   class queue_elem *e = XNEW (class queue_elem);
    447   rtx t1 = rtx_alloc (DEFINE_ATTR);
    448   XSTR (t1, 0) = name;
    449   XSTR (t1, 1) = "no,yes";
    450   XEXP (t1, 2) = rtx_alloc (CONST_STRING);
    451   XSTR (XEXP (t1, 2), 0) = "yes";
    452   e->data = t1;
    453   e->loc = file_location ("built-in", -1, -1);
    454   e->next = define_attr_queue;
    455   define_attr_queue = e;
    456 
    457 }
    458 
    459 /* Recursively remove constraints from an rtx.  */
    460 
    461 static void
    462 remove_constraints (rtx part)
    463 {
    464   int i, j;
    465   const char *format_ptr;
    466 
    467   if (part == 0)
    468     return;
    469 
    470   if (GET_CODE (part) == MATCH_OPERAND)
    471     XSTR (part, 2) = "";
    472   else if (GET_CODE (part) == MATCH_SCRATCH)
    473     XSTR (part, 1) = "";
    474 
    475   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
    476 
    477   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
    478     switch (*format_ptr++)
    479       {
    480       case 'e':
    481       case 'u':
    482 	remove_constraints (XEXP (part, i));
    483 	break;
    484       case 'E':
    485 	if (XVEC (part, i) != NULL)
    486 	  for (j = 0; j < XVECLEN (part, i); j++)
    487 	    remove_constraints (XVECEXP (part, i, j));
    488 	break;
    489       }
    490 }
    491 
    492 /* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
    493    with MATCH_OP_DUPs in X.  */
    494 
    495 static rtx
    496 replace_operands_with_dups (rtx x)
    497 {
    498   if (x == 0)
    499     return x;
    500 
    501   rtx newx;
    502   if (GET_CODE (x) == MATCH_OPERAND)
    503     {
    504       newx = rtx_alloc (MATCH_DUP);
    505       XINT (newx, 0) = XINT (x, 0);
    506       x = newx;
    507     }
    508   else if (GET_CODE (x) == MATCH_OPERATOR)
    509     {
    510       newx = rtx_alloc (MATCH_OP_DUP);
    511       XINT (newx, 0) = XINT (x, 0);
    512       XVEC (newx, 1) = XVEC (x, 2);
    513       x = newx;
    514     }
    515   else
    516     newx = shallow_copy_rtx (x);
    517 
    518   const char *format_ptr = GET_RTX_FORMAT (GET_CODE (x));
    519   for (int i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
    520     switch (*format_ptr++)
    521       {
    522       case 'e':
    523       case 'u':
    524 	XEXP (newx, i) = replace_operands_with_dups (XEXP (x, i));
    525 	break;
    526       case 'E':
    527 	if (XVEC (x, i) != NULL)
    528 	  {
    529 	    XVEC (newx, i) = rtvec_alloc (XVECLEN (x, i));
    530 	    for (int j = 0; j < XVECLEN (x, i); j++)
    531 	      XVECEXP (newx, i, j)
    532 		= replace_operands_with_dups (XVECEXP (x, i, j));
    533 	  }
    534 	break;
    535       }
    536   return newx;
    537 }
    538 
    539 /* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
    540    a sequence that should be generated by the splitter.  */
    541 
    542 static rtvec
    543 gen_rewrite_sequence (rtvec vec)
    544 {
    545   rtvec new_vec = rtvec_alloc (1);
    546   rtx x = add_implicit_parallel (vec);
    547   RTVEC_ELT (new_vec, 0) = replace_operands_with_dups (x);
    548   return new_vec;
    549 }
    550 
    551 /* Process a top level rtx in some way, queuing as appropriate.  */
    552 
    553 static void
    554 process_rtx (rtx desc, file_location loc)
    555 {
    556   switch (GET_CODE (desc))
    557     {
    558     case DEFINE_INSN:
    559       queue_pattern (desc, &define_insn_tail, loc);
    560       break;
    561 
    562     case DEFINE_COND_EXEC:
    563       queue_pattern (desc, &define_cond_exec_tail, loc);
    564       break;
    565 
    566     case DEFINE_SUBST:
    567       queue_pattern (desc, &define_subst_tail, loc);
    568       break;
    569 
    570     case DEFINE_SUBST_ATTR:
    571       queue_pattern (desc, &define_subst_attr_tail, loc);
    572       break;
    573 
    574     case DEFINE_ATTR:
    575     case DEFINE_ENUM_ATTR:
    576       queue_pattern (desc, &define_attr_tail, loc);
    577       break;
    578 
    579     case DEFINE_PREDICATE:
    580     case DEFINE_SPECIAL_PREDICATE:
    581       process_define_predicate (desc, loc);
    582       /* Fall through.  */
    583 
    584     case DEFINE_CONSTRAINT:
    585     case DEFINE_REGISTER_CONSTRAINT:
    586     case DEFINE_MEMORY_CONSTRAINT:
    587     case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
    588     case DEFINE_RELAXED_MEMORY_CONSTRAINT:
    589     case DEFINE_ADDRESS_CONSTRAINT:
    590       queue_pattern (desc, &define_pred_tail, loc);
    591       break;
    592 
    593     case DEFINE_INSN_AND_SPLIT:
    594     case DEFINE_INSN_AND_REWRITE:
    595       {
    596 	const char *split_cond;
    597 	rtx split;
    598 	rtvec attr;
    599 	int i;
    600 	class queue_elem *insn_elem;
    601 	class queue_elem *split_elem;
    602 	int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);
    603 
    604 	/* Create a split with values from the insn_and_split.  */
    605 	split = rtx_alloc (DEFINE_SPLIT);
    606 
    607 	i = XVECLEN (desc, 1);
    608 	XVEC (split, 0) = rtvec_alloc (i);
    609 	while (--i >= 0)
    610 	  {
    611 	    XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
    612 	    remove_constraints (XVECEXP (split, 0, i));
    613 	  }
    614 
    615 	/* If the split condition starts with "&&", append it to the
    616 	   insn condition to create the new split condition.  */
    617 	split_cond = XSTR (desc, 4);
    618 	if (split_cond[0] == '&' && split_cond[1] == '&')
    619 	  {
    620 	    rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
    621 	    split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
    622 							    split_cond + 2);
    623 	  }
    624 	else if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
    625 	  error_at (loc, "the rewrite condition must start with `&&'");
    626 	XSTR (split, 1) = split_cond;
    627 	if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
    628 	  XVEC (split, 2) = gen_rewrite_sequence (XVEC (desc, 1));
    629 	else
    630 	  XVEC (split, 2) = XVEC (desc, 5);
    631 	XSTR (split, 3) = XSTR (desc, split_code);
    632 
    633 	/* Fix up the DEFINE_INSN.  */
    634 	attr = XVEC (desc, split_code + 1);
    635 	PUT_CODE (desc, DEFINE_INSN);
    636 	XVEC (desc, 4) = attr;
    637 
    638 	/* Queue them.  */
    639 	insn_elem = queue_pattern (desc, &define_insn_tail, loc);
    640 	split_elem = queue_pattern (split, &other_tail, loc);
    641 	insn_elem->split = split_elem;
    642 	break;
    643       }
    644 
    645     default:
    646       queue_pattern (desc, &other_tail, loc);
    647       break;
    648     }
    649 }
    650 
    651 /* Return true if attribute PREDICABLE is true for ELEM, which holds
    653    a DEFINE_INSN.  */
    654 
    655 static int
    656 is_predicable (class queue_elem *elem)
    657 {
    658   rtvec vec = XVEC (elem->data, 4);
    659   const char *value;
    660   int i;
    661 
    662   if (! vec)
    663     return predicable_default;
    664 
    665   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
    666     {
    667       rtx sub = RTVEC_ELT (vec, i);
    668       switch (GET_CODE (sub))
    669 	{
    670 	case SET_ATTR:
    671 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
    672 	    {
    673 	      value = XSTR (sub, 1);
    674 	      goto found;
    675 	    }
    676 	  break;
    677 
    678 	case SET_ATTR_ALTERNATIVE:
    679 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
    680 	    {
    681 	      error_at (elem->loc, "multiple alternatives for `predicable'");
    682 	      return 0;
    683 	    }
    684 	  break;
    685 
    686 	case SET:
    687 	  if (GET_CODE (SET_DEST (sub)) != ATTR
    688 	      || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
    689 	    break;
    690 	  sub = SET_SRC (sub);
    691 	  if (GET_CODE (sub) == CONST_STRING)
    692 	    {
    693 	      value = XSTR (sub, 0);
    694 	      goto found;
    695 	    }
    696 
    697 	  /* ??? It would be possible to handle this if we really tried.
    698 	     It's not easy though, and I'm not going to bother until it
    699 	     really proves necessary.  */
    700 	  error_at (elem->loc, "non-constant value for `predicable'");
    701 	  return 0;
    702 
    703 	default:
    704 	  gcc_unreachable ();
    705 	}
    706     }
    707 
    708   return predicable_default;
    709 
    710  found:
    711   /* Find out which value we're looking at.  Multiple alternatives means at
    712      least one is predicable.  */
    713   if (strchr (value, ',') != NULL)
    714     return 1;
    715   if (strcmp (value, predicable_true) == 0)
    716     return 1;
    717   if (strcmp (value, predicable_false) == 0)
    718     return 0;
    719 
    720   error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
    721   return 0;
    722 }
    723 
    724 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it.  */
    725 static void
    726 change_subst_attribute (class queue_elem *elem,
    727 			class queue_elem *subst_elem,
    728 			const char *new_value)
    729 {
    730   rtvec attrs_vec = XVEC (elem->data, 4);
    731   const char *subst_name = XSTR (subst_elem->data, 0);
    732   int i;
    733 
    734   if (! attrs_vec)
    735     return;
    736 
    737   for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
    738     {
    739       rtx cur_attr = RTVEC_ELT (attrs_vec, i);
    740       if (GET_CODE (cur_attr) != SET_ATTR)
    741 	continue;
    742       if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
    743 	{
    744 	  XSTR (cur_attr, 1) = new_value;
    745 	  return;
    746 	}
    747     }
    748 }
    749 
    750 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
    751    represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
    752    DEFINE_SUBST isn't applied to patterns without such attribute.  In other
    753    words, we suppose the default value of the attribute to be 'no' since it is
    754    always generated automatically in read-rtl.cc.  */
    755 static bool
    756 has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
    757 {
    758   rtvec attrs_vec = XVEC (elem->data, 4);
    759   const char *value, *subst_name = XSTR (subst_elem->data, 0);
    760   int i;
    761 
    762   if (! attrs_vec)
    763     return false;
    764 
    765   for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
    766     {
    767       rtx cur_attr = RTVEC_ELT (attrs_vec, i);
    768       switch (GET_CODE (cur_attr))
    769 	{
    770 	case SET_ATTR:
    771 	  if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
    772 	    {
    773 	      value = XSTR (cur_attr, 1);
    774 	      goto found;
    775 	    }
    776 	  break;
    777 
    778 	case SET:
    779 	  if (GET_CODE (SET_DEST (cur_attr)) != ATTR
    780 	      || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
    781 	    break;
    782 	  cur_attr = SET_SRC (cur_attr);
    783 	  if (GET_CODE (cur_attr) == CONST_STRING)
    784 	    {
    785 	      value = XSTR (cur_attr, 0);
    786 	      goto found;
    787 	    }
    788 
    789 	  /* Only (set_attr "subst" "yes/no") and
    790 		  (set (attr "subst" (const_string "yes/no")))
    791 	     are currently allowed.  */
    792 	  error_at (elem->loc, "unsupported value for `%s'", subst_name);
    793 	  return false;
    794 
    795 	case SET_ATTR_ALTERNATIVE:
    796 	  if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
    797 	    error_at (elem->loc,
    798 		      "%s: `set_attr_alternative' is unsupported by "
    799 		      "`define_subst'", XSTR (elem->data, 0));
    800 	  return false;
    801 
    802 
    803 	default:
    804 	  gcc_unreachable ();
    805 	}
    806     }
    807 
    808   return false;
    809 
    810  found:
    811   if (strcmp (value, subst_true) == 0)
    812     return true;
    813   if (strcmp (value, subst_false) == 0)
    814     return false;
    815 
    816   error_at (elem->loc, "unknown value `%s' for `%s' attribute",
    817 	    value, subst_name);
    818   return false;
    819 }
    820 
    821 /* Compare RTL-template of original define_insn X to input RTL-template of
    822    define_subst PT.  Return 1 if the templates match, 0 otherwise.
    823    During the comparison, the routine also fills global_array OPERAND_DATA.  */
    824 static bool
    825 subst_pattern_match (rtx x, rtx pt, file_location loc)
    826 {
    827   RTX_CODE code, code_pt;
    828   int i, j, len;
    829   const char *fmt, *pred_name;
    830 
    831   code = GET_CODE (x);
    832   code_pt = GET_CODE (pt);
    833 
    834   if (code_pt == MATCH_OPERAND)
    835     {
    836       /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
    837 	 always accept them.  */
    838       if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
    839 	  && (code != MATCH_DUP && code != MATCH_OP_DUP))
    840 	return false; /* Modes don't match.  */
    841 
    842       if (code == MATCH_OPERAND)
    843 	{
    844 	  pred_name = XSTR (pt, 1);
    845 	  if (pred_name[0] != 0)
    846 	    {
    847 	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
    848 	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
    849 		return false; /* Predicates don't match.  */
    850 	    }
    851 	}
    852 
    853       gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
    854       operand_data[XINT (pt, 0)] = x;
    855       return true;
    856     }
    857 
    858   if (code_pt == MATCH_OPERATOR)
    859     {
    860       int x_vecexp_pos = -1;
    861 
    862       /* Compare modes.  */
    863       if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
    864 	return false;
    865 
    866       /* In case X is also match_operator, compare predicates.  */
    867       if (code == MATCH_OPERATOR)
    868 	{
    869 	  pred_name = XSTR (pt, 1);
    870 	  if (pred_name[0] != 0)
    871 	    {
    872 	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
    873 	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
    874 		return false;
    875 	    }
    876 	}
    877 
    878       /* Compare operands.
    879 	 MATCH_OPERATOR in input template could match in original template
    880 	 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
    881 	 In the first case operands are at (XVECEXP (x, 2, j)), in the second
    882 	 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
    883 	 X_VECEXP_POS variable shows, where to look for these operands.  */
    884       if (code == UNSPEC
    885 	  || code == UNSPEC_VOLATILE)
    886 	x_vecexp_pos = 0;
    887       else if (code == MATCH_OPERATOR)
    888 	x_vecexp_pos = 2;
    889       else
    890 	x_vecexp_pos = -1;
    891 
    892       /* MATCH_OPERATOR or UNSPEC case.  */
    893       if (x_vecexp_pos >= 0)
    894 	{
    895 	  /* Compare operands number in X and PT.  */
    896 	  if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
    897 	    return false;
    898 	  for (j = 0; j < XVECLEN (pt, 2); j++)
    899 	    if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
    900 				      XVECEXP (pt, 2, j), loc))
    901 	      return false;
    902 	}
    903 
    904       /* Ordinary operator.  */
    905       else
    906 	{
    907 	  /* Compare operands number in X and PT.
    908 	     We count operands differently for X and PT since we compare
    909 	     an operator (with operands directly in RTX) and MATCH_OPERATOR
    910 	     (that has a vector with operands).  */
    911 	  if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
    912 	    return false;
    913 	  for (j = 0; j < XVECLEN (pt, 2); j++)
    914 	    if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
    915 	      return false;
    916 	}
    917 
    918       /* Store the operand to OPERAND_DATA array.  */
    919       gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
    920       operand_data[XINT (pt, 0)] = x;
    921       return true;
    922     }
    923 
    924   if (code_pt == MATCH_PAR_DUP
    925       || code_pt == MATCH_DUP
    926       || code_pt == MATCH_OP_DUP
    927       || code_pt == MATCH_SCRATCH
    928       || code_pt == MATCH_PARALLEL)
    929     {
    930       /* Currently interface for these constructions isn't defined -
    931 	 probably they aren't needed in input template of define_subst at all.
    932 	 So, for now their usage in define_subst is forbidden.  */
    933       error_at (loc, "%s cannot be used in define_subst",
    934 		GET_RTX_NAME (code_pt));
    935     }
    936 
    937   gcc_assert (code != MATCH_PAR_DUP
    938       && code_pt != MATCH_DUP
    939       && code_pt != MATCH_OP_DUP
    940       && code_pt != MATCH_SCRATCH
    941       && code_pt != MATCH_PARALLEL
    942       && code_pt != MATCH_OPERAND
    943       && code_pt != MATCH_OPERATOR);
    944   /* If PT is none of the handled above, then we match only expressions with
    945      the same code in X.  */
    946   if (code != code_pt)
    947     return false;
    948 
    949   fmt = GET_RTX_FORMAT (code_pt);
    950   len = GET_RTX_LENGTH (code_pt);
    951 
    952   for (i = 0; i < len; i++)
    953     {
    954       if (fmt[i] == '0')
    955 	break;
    956 
    957       switch (fmt[i])
    958 	{
    959 	case 'r': case 'p': case 'i': case 'w': case 's':
    960 	  continue;
    961 
    962 	case 'e': case 'u':
    963 	  if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
    964 	    return false;
    965 	  break;
    966 	case 'E':
    967 	  {
    968 	    if (XVECLEN (x, i) != XVECLEN (pt, i))
    969 	      return false;
    970 	    for (j = 0; j < XVECLEN (pt, i); j++)
    971 	      if (!subst_pattern_match (XVECEXP (x, i, j),
    972 					XVECEXP (pt, i, j), loc))
    973 		return false;
    974 	    break;
    975 	  }
    976 	default:
    977 	  gcc_unreachable ();
    978 	}
    979     }
    980 
    981   return true;
    982 }
    983 
    984 /* Examine the attribute "predicable"; discover its boolean values
    985    and its default.  */
    986 
    987 static void
    988 identify_predicable_attribute (void)
    989 {
    990   class queue_elem *elem;
    991   char *p_true, *p_false;
    992   const char *value;
    993 
    994   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
    995   for (elem = define_attr_queue; elem ; elem = elem->next)
    996     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
    997       goto found;
    998 
    999   error_at (define_cond_exec_queue->loc,
   1000 	    "attribute `predicable' not defined");
   1001   return;
   1002 
   1003  found:
   1004   value = XSTR (elem->data, 1);
   1005   p_false = xstrdup (value);
   1006   p_true = strchr (p_false, ',');
   1007   if (p_true == NULL || strchr (++p_true, ',') != NULL)
   1008     {
   1009       error_at (elem->loc, "attribute `predicable' is not a boolean");
   1010       free (p_false);
   1011       return;
   1012     }
   1013   p_true[-1] = '\0';
   1014 
   1015   predicable_true = p_true;
   1016   predicable_false = p_false;
   1017 
   1018   switch (GET_CODE (XEXP (elem->data, 2)))
   1019     {
   1020     case CONST_STRING:
   1021       value = XSTR (XEXP (elem->data, 2), 0);
   1022       break;
   1023 
   1024     case CONST:
   1025       error_at (elem->loc, "attribute `predicable' cannot be const");
   1026       free (p_false);
   1027       return;
   1028 
   1029     default:
   1030       error_at (elem->loc,
   1031 		"attribute `predicable' must have a constant default");
   1032       free (p_false);
   1033       return;
   1034     }
   1035 
   1036   if (strcmp (value, p_true) == 0)
   1037     predicable_default = 1;
   1038   else if (strcmp (value, p_false) == 0)
   1039     predicable_default = 0;
   1040   else
   1041     {
   1042       error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
   1043 		value);
   1044       free (p_false);
   1045     }
   1046 }
   1047 
   1048 /* Return the number of alternatives in constraint S.  */
   1049 
   1050 static int
   1051 n_alternatives (const char *s)
   1052 {
   1053   int n = 1;
   1054 
   1055   if (s)
   1056     while (*s)
   1057       n += (*s++ == ',');
   1058 
   1059   return n;
   1060 }
   1061 
   1062 /* The routine scans rtl PATTERN, find match_operand in it and counts
   1063    number of alternatives.  If PATTERN contains several match_operands
   1064    with different number of alternatives, error is emitted, and the
   1065    routine returns 0.  If all match_operands in PATTERN have the same
   1066    number of alternatives, it's stored in N_ALT, and the routine returns 1.
   1067    LOC is the location of PATTERN, for error reporting.  */
   1068 static int
   1069 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
   1070 {
   1071   const char *fmt;
   1072   enum rtx_code code;
   1073   int i, j, len;
   1074 
   1075   if (!n_alt)
   1076     return 0;
   1077 
   1078   code = GET_CODE (pattern);
   1079   switch (code)
   1080     {
   1081     case MATCH_OPERAND:
   1082       i = n_alternatives (XSTR (pattern, 2));
   1083       /* n_alternatives returns 1 if constraint string is empty -
   1084 	 here we fix it up.  */
   1085       if (!*(XSTR (pattern, 2)))
   1086 	i = 0;
   1087       if (*n_alt <= 0)
   1088 	*n_alt = i;
   1089 
   1090       else if (i && i != *n_alt)
   1091 	{
   1092 	  error_at (loc, "wrong number of alternatives in operand %d",
   1093 		    XINT (pattern, 0));
   1094 	  return 0;
   1095 	}
   1096 
   1097     default:
   1098       break;
   1099     }
   1100 
   1101   fmt = GET_RTX_FORMAT (code);
   1102   len = GET_RTX_LENGTH (code);
   1103   for (i = 0; i < len; i++)
   1104     {
   1105       switch (fmt[i])
   1106 	{
   1107 	case 'e': case 'u':
   1108 	  if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
   1109 	    return 0;
   1110 	  break;
   1111 
   1112 	case 'V':
   1113 	  if (XVEC (pattern, i) == NULL)
   1114 	    break;
   1115 	  /* FALLTHRU */
   1116 
   1117 	case 'E':
   1118 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   1119 	    if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
   1120 	      return 0;
   1121 	  break;
   1122 
   1123 	case 'r': case 'p': case 'i': case 'w':
   1124 	case '0': case 's': case 'S': case 'T':
   1125 	  break;
   1126 
   1127 	default:
   1128 	  gcc_unreachable ();
   1129 	}
   1130     }
   1131     return 1;
   1132 }
   1133 
   1134 /* Determine how many alternatives there are in INSN, and how many
   1135    operands.  */
   1136 
   1137 static void
   1138 collect_insn_data (rtx pattern, int *palt, int *pmax)
   1139 {
   1140   const char *fmt;
   1141   enum rtx_code code;
   1142   int i, j, len;
   1143 
   1144   code = GET_CODE (pattern);
   1145   switch (code)
   1146     {
   1147     case MATCH_OPERAND:
   1148     case MATCH_SCRATCH:
   1149       i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
   1150       *palt = (i > *palt ? i : *palt);
   1151       /* Fall through.  */
   1152 
   1153     case MATCH_OPERATOR:
   1154     case MATCH_PARALLEL:
   1155       i = XINT (pattern, 0);
   1156       if (i > *pmax)
   1157 	*pmax = i;
   1158       break;
   1159 
   1160     default:
   1161       break;
   1162     }
   1163 
   1164   fmt = GET_RTX_FORMAT (code);
   1165   len = GET_RTX_LENGTH (code);
   1166   for (i = 0; i < len; i++)
   1167     {
   1168       switch (fmt[i])
   1169 	{
   1170 	case 'e': case 'u':
   1171 	  collect_insn_data (XEXP (pattern, i), palt, pmax);
   1172 	  break;
   1173 
   1174 	case 'V':
   1175 	  if (XVEC (pattern, i) == NULL)
   1176 	    break;
   1177 	  /* Fall through.  */
   1178 	case 'E':
   1179 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   1180 	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
   1181 	  break;
   1182 
   1183 	case 'r': case 'p': case 'i': case 'w':
   1184 	case '0': case 's': case 'S': case 'T':
   1185 	  break;
   1186 
   1187 	default:
   1188 	  gcc_unreachable ();
   1189 	}
   1190     }
   1191 }
   1192 
   1193 static rtx
   1194 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
   1195 			  file_location loc)
   1196 {
   1197   const char *fmt;
   1198   enum rtx_code code;
   1199   int i, j, len;
   1200 
   1201   code = GET_CODE (pattern);
   1202   switch (code)
   1203     {
   1204     case MATCH_OPERAND:
   1205       {
   1206 	const char *c = XSTR (pattern, 2);
   1207 
   1208 	if (n_alternatives (c) != 1)
   1209 	  {
   1210 	    error_at (loc, "too many alternatives for operand %d",
   1211 		      XINT (pattern, 0));
   1212 	    return NULL;
   1213 	  }
   1214 
   1215 	/* Replicate C as needed to fill out ALT alternatives.  */
   1216 	if (c && *c && alt > 1)
   1217 	  {
   1218 	    size_t c_len = strlen (c);
   1219 	    size_t len = alt * (c_len + 1);
   1220 	    char *new_c = XNEWVEC (char, len);
   1221 
   1222 	    memcpy (new_c, c, c_len);
   1223 	    for (i = 1; i < alt; ++i)
   1224 	      {
   1225 		new_c[i * (c_len + 1) - 1] = ',';
   1226 		memcpy (&new_c[i * (c_len + 1)], c, c_len);
   1227 	      }
   1228 	    new_c[len - 1] = '\0';
   1229 	    XSTR (pattern, 2) = new_c;
   1230 	  }
   1231       }
   1232       /* Fall through.  */
   1233 
   1234     case MATCH_OPERATOR:
   1235     case MATCH_SCRATCH:
   1236     case MATCH_PARALLEL:
   1237     case MATCH_DUP:
   1238       XINT (pattern, 0) += max_op;
   1239       break;
   1240 
   1241     default:
   1242       break;
   1243     }
   1244 
   1245   fmt = GET_RTX_FORMAT (code);
   1246   len = GET_RTX_LENGTH (code);
   1247   for (i = 0; i < len; i++)
   1248     {
   1249       rtx r;
   1250 
   1251       switch (fmt[i])
   1252 	{
   1253 	case 'e': case 'u':
   1254 	  r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
   1255 	  if (r == NULL)
   1256 	    return r;
   1257 	  break;
   1258 
   1259 	case 'E':
   1260 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   1261 	    {
   1262 	      r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
   1263 					    alt, max_op, loc);
   1264 	      if (r == NULL)
   1265 		return r;
   1266 	    }
   1267 	  break;
   1268 
   1269 	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
   1270 	  break;
   1271 
   1272 	default:
   1273 	  gcc_unreachable ();
   1274 	}
   1275     }
   1276 
   1277   return pattern;
   1278 }
   1279 
   1280 /* Duplicate constraints in PATTERN.  If pattern is from original
   1281    rtl-template, we need to duplicate each alternative - for that we
   1282    need to use duplicate_each_alternative () as a functor ALTER.
   1283    If pattern is from output-pattern of define_subst, we need to
   1284    duplicate constraints in another way - with duplicate_alternatives ().
   1285    N_DUP is multiplication factor.  */
   1286 static rtx
   1287 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
   1288 {
   1289   const char *fmt;
   1290   enum rtx_code code;
   1291   int i, j, len;
   1292 
   1293   code = GET_CODE (pattern);
   1294   switch (code)
   1295     {
   1296     case MATCH_OPERAND:
   1297       XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
   1298       break;
   1299     case MATCH_SCRATCH:
   1300       XSTR (pattern, 1) = alter (XSTR (pattern, 1), n_dup);
   1301       break;
   1302 
   1303     default:
   1304       break;
   1305     }
   1306 
   1307   fmt = GET_RTX_FORMAT (code);
   1308   len = GET_RTX_LENGTH (code);
   1309   for (i = 0; i < len; i++)
   1310     {
   1311       rtx r;
   1312 
   1313       switch (fmt[i])
   1314 	{
   1315 	case 'e': case 'u':
   1316 	  r = alter_constraints (XEXP (pattern, i), n_dup, alter);
   1317 	  if (r == NULL)
   1318 	    return r;
   1319 	  break;
   1320 
   1321 	case 'E':
   1322 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   1323 	    {
   1324 	      r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
   1325 	      if (r == NULL)
   1326 		return r;
   1327 	    }
   1328 	  break;
   1329 
   1330 	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
   1331 	  break;
   1332 
   1333 	default:
   1334 	  break;
   1335 	}
   1336     }
   1337 
   1338   return pattern;
   1339 }
   1340 
   1341 static const char *
   1342 alter_test_for_insn (class queue_elem *ce_elem,
   1343 		     class queue_elem *insn_elem)
   1344 {
   1345   return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
   1346 					    XSTR (insn_elem->data, 2));
   1347 }
   1348 
   1349 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
   1350    to take "ce_enabled" into account.  Return the new expression.  */
   1351 static rtx
   1352 modify_attr_enabled_ce (rtx val)
   1353 {
   1354   rtx eq_attr, str;
   1355   rtx ite;
   1356   eq_attr = rtx_alloc (EQ_ATTR);
   1357   ite = rtx_alloc (IF_THEN_ELSE);
   1358   str = rtx_alloc (CONST_STRING);
   1359 
   1360   XSTR (eq_attr, 0) = "ce_enabled";
   1361   XSTR (eq_attr, 1) = "yes";
   1362   XSTR (str, 0) = "no";
   1363   XEXP (ite, 0) = eq_attr;
   1364   XEXP (ite, 1) = val;
   1365   XEXP (ite, 2) = str;
   1366 
   1367   return ite;
   1368 }
   1369 
   1370 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
   1371    from a define_insn pattern.  We must modify the "predicable" attribute
   1372    to be named "ce_enabled", and also change any "enabled" attribute that's
   1373    present so that it takes ce_enabled into account.
   1374    We rely on the fact that INSN was created with copy_rtx, and modify data
   1375    in-place.  */
   1376 
   1377 static void
   1378 alter_attrs_for_insn (rtx insn)
   1379 {
   1380   static bool global_changes_made = false;
   1381   rtvec vec = XVEC (insn, 4);
   1382   rtvec new_vec;
   1383   rtx val, set;
   1384   int num_elem;
   1385   int predicable_idx = -1;
   1386   int enabled_idx = -1;
   1387   int i;
   1388 
   1389   if (! vec)
   1390     return;
   1391 
   1392   num_elem = GET_NUM_ELEM (vec);
   1393   for (i = num_elem - 1; i >= 0; --i)
   1394     {
   1395       rtx sub = RTVEC_ELT (vec, i);
   1396       switch (GET_CODE (sub))
   1397 	{
   1398 	case SET_ATTR:
   1399 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
   1400 	    {
   1401 	      predicable_idx = i;
   1402 	      XSTR (sub, 0) = "ce_enabled";
   1403 	    }
   1404 	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
   1405 	    {
   1406 	      enabled_idx = i;
   1407 	      XSTR (sub, 0) = "nonce_enabled";
   1408 	    }
   1409 	  break;
   1410 
   1411 	case SET_ATTR_ALTERNATIVE:
   1412 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
   1413 	    /* We already give an error elsewhere.  */
   1414 	    return;
   1415 	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
   1416 	    {
   1417 	      enabled_idx = i;
   1418 	      XSTR (sub, 0) = "nonce_enabled";
   1419 	    }
   1420 	  break;
   1421 
   1422 	case SET:
   1423 	  if (GET_CODE (SET_DEST (sub)) != ATTR)
   1424 	    break;
   1425 	  if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
   1426 	    {
   1427 	      sub = SET_SRC (sub);
   1428 	      if (GET_CODE (sub) == CONST_STRING)
   1429 		{
   1430 		  predicable_idx = i;
   1431 		  XSTR (sub, 0) = "ce_enabled";
   1432 		}
   1433 	      else
   1434 		/* We already give an error elsewhere.  */
   1435 		return;
   1436 	      break;
   1437 	    }
   1438 	  if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
   1439 	    {
   1440 	      enabled_idx = i;
   1441 	      XSTR (SET_DEST (sub), 0) = "nonce_enabled";
   1442 	    }
   1443 	  break;
   1444 
   1445 	default:
   1446 	  gcc_unreachable ();
   1447 	}
   1448     }
   1449   if (predicable_idx == -1)
   1450     return;
   1451 
   1452   if (!global_changes_made)
   1453     {
   1454       class queue_elem *elem;
   1455 
   1456       global_changes_made = true;
   1457       add_define_attr ("ce_enabled");
   1458       add_define_attr ("nonce_enabled");
   1459 
   1460       for (elem = define_attr_queue; elem ; elem = elem->next)
   1461 	if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
   1462 	  {
   1463 	    XEXP (elem->data, 2)
   1464 	      = modify_attr_enabled_ce (XEXP (elem->data, 2));
   1465 	  }
   1466     }
   1467   if (enabled_idx == -1)
   1468     return;
   1469 
   1470   new_vec = rtvec_alloc (num_elem + 1);
   1471   for (i = 0; i < num_elem; i++)
   1472     RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
   1473   val = rtx_alloc (IF_THEN_ELSE);
   1474   XEXP (val, 0) = rtx_alloc (EQ_ATTR);
   1475   XEXP (val, 1) = rtx_alloc (CONST_STRING);
   1476   XEXP (val, 2) = rtx_alloc (CONST_STRING);
   1477   XSTR (XEXP (val, 0), 0) = "nonce_enabled";
   1478   XSTR (XEXP (val, 0), 1) = "yes";
   1479   XSTR (XEXP (val, 1), 0) = "yes";
   1480   XSTR (XEXP (val, 2), 0) = "no";
   1481   set = rtx_alloc (SET);
   1482   SET_DEST (set) = rtx_alloc (ATTR);
   1483   XSTR (SET_DEST (set), 0) = "enabled";
   1484   SET_SRC (set) = modify_attr_enabled_ce (val);
   1485   RTVEC_ELT (new_vec, i) = set;
   1486   XVEC (insn, 4) = new_vec;
   1487 }
   1488 
   1489 /* As number of constraints is changed after define_subst, we need to
   1490    process attributes as well - we need to duplicate them the same way
   1491    that we duplicated constraints in original pattern
   1492    ELEM is a queue element, containing our rtl-template,
   1493    N_DUP - multiplication factor.  */
   1494 static void
   1495 alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
   1496 {
   1497   rtvec vec = XVEC (elem->data, 4);
   1498   int num_elem;
   1499   int i;
   1500 
   1501   if (n_dup < 2 || ! vec)
   1502     return;
   1503 
   1504   num_elem = GET_NUM_ELEM (vec);
   1505   for (i = num_elem - 1; i >= 0; --i)
   1506     {
   1507       rtx sub = RTVEC_ELT (vec, i);
   1508       switch (GET_CODE (sub))
   1509 	{
   1510 	case SET_ATTR:
   1511 	  if (strchr (XSTR (sub, 1), ',') != NULL)
   1512 	    XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
   1513 	  break;
   1514 
   1515 	case SET_ATTR_ALTERNATIVE:
   1516 	case SET:
   1517 	  error_at (elem->loc,
   1518 		    "%s: `define_subst' does not support attributes "
   1519 		    "assigned by `set' and `set_attr_alternative'",
   1520 		    XSTR (elem->data, 0));
   1521 	  return;
   1522 
   1523 	default:
   1524 	  gcc_unreachable ();
   1525 	}
   1526     }
   1527 }
   1528 
   1529 /* Adjust all of the operand numbers in SRC to match the shift they'll
   1530    get from an operand displacement of DISP.  Return a pointer after the
   1531    adjusted string.  */
   1532 
   1533 static char *
   1534 shift_output_template (char *dest, const char *src, int disp)
   1535 {
   1536   while (*src)
   1537     {
   1538       char c = *src++;
   1539       *dest++ = c;
   1540       if (c == '%')
   1541 	{
   1542 	  c = *src++;
   1543 	  if (ISDIGIT ((unsigned char) c))
   1544 	    c += disp;
   1545 	  else if (ISALPHA (c))
   1546 	    {
   1547 	      *dest++ = c;
   1548 	      c = *src++ + disp;
   1549 	    }
   1550 	  *dest++ = c;
   1551 	}
   1552     }
   1553 
   1554   return dest;
   1555 }
   1556 
   1557 static const char *
   1558 alter_output_for_insn (class queue_elem *ce_elem,
   1559 		       class queue_elem *insn_elem,
   1560 		       int alt, int max_op)
   1561 {
   1562   const char *ce_out, *insn_out;
   1563   char *result, *p;
   1564   size_t len, ce_len, insn_len;
   1565 
   1566   /* ??? Could coordinate with genoutput to not duplicate code here.  */
   1567 
   1568   ce_out = XSTR (ce_elem->data, 2);
   1569   insn_out = XTMPL (insn_elem->data, 3);
   1570   if (!ce_out || *ce_out == '\0')
   1571     return insn_out;
   1572 
   1573   ce_len = strlen (ce_out);
   1574   insn_len = strlen (insn_out);
   1575 
   1576   if (*insn_out == '*')
   1577     /* You must take care of the predicate yourself.  */
   1578     return insn_out;
   1579 
   1580   if (*insn_out == '@')
   1581     {
   1582       len = (ce_len + 1) * alt + insn_len + 1;
   1583       p = result = XNEWVEC (char, len);
   1584 
   1585       do
   1586 	{
   1587 	  do
   1588 	    *p++ = *insn_out++;
   1589 	  while (ISSPACE ((unsigned char) *insn_out));
   1590 
   1591 	  if (*insn_out != '#')
   1592 	    {
   1593 	      p = shift_output_template (p, ce_out, max_op);
   1594 	      *p++ = ' ';
   1595 	    }
   1596 
   1597 	  do
   1598 	    *p++ = *insn_out++;
   1599 	  while (*insn_out && *insn_out != '\n');
   1600 	}
   1601       while (*insn_out);
   1602       *p = '\0';
   1603     }
   1604   else
   1605     {
   1606       len = ce_len + 1 + insn_len + 1;
   1607       result = XNEWVEC (char, len);
   1608 
   1609       p = shift_output_template (result, ce_out, max_op);
   1610       *p++ = ' ';
   1611       memcpy (p, insn_out, insn_len + 1);
   1612     }
   1613 
   1614   return result;
   1615 }
   1616 
   1617 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
   1618    string, duplicated N_DUP times.  */
   1619 
   1620 static const char *
   1621 duplicate_alternatives (const char * str, int n_dup)
   1622 {
   1623   int i, len, new_len;
   1624   char *result, *sp;
   1625   const char *cp;
   1626 
   1627   if (n_dup < 2)
   1628     return str;
   1629 
   1630   while (ISSPACE (*str))
   1631     str++;
   1632 
   1633   if (*str == '\0')
   1634     return str;
   1635 
   1636   cp = str;
   1637   len = strlen (str);
   1638   new_len = (len + 1) * n_dup;
   1639 
   1640   sp = result = XNEWVEC (char, new_len);
   1641 
   1642   /* Global modifier characters mustn't be duplicated: skip if found.  */
   1643   if (*cp == '=' || *cp == '+' || *cp == '%')
   1644     {
   1645       *sp++ = *cp++;
   1646       len--;
   1647     }
   1648 
   1649   /* Copy original constraints N_DUP times.  */
   1650   for (i = 0; i < n_dup; i++, sp += len+1)
   1651     {
   1652       memcpy (sp, cp, len);
   1653       *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
   1654     }
   1655 
   1656   return result;
   1657 }
   1658 
   1659 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
   1660    each alternative from the original string is duplicated N_DUP times.  */
   1661 static const char *
   1662 duplicate_each_alternative (const char * str, int n_dup)
   1663 {
   1664   int i, len, new_len;
   1665   char *result, *sp, *ep, *cp;
   1666 
   1667   if (n_dup < 2)
   1668     return str;
   1669 
   1670   while (ISSPACE (*str))
   1671     str++;
   1672 
   1673   if (*str == '\0')
   1674     return str;
   1675 
   1676   cp = xstrdup (str);
   1677 
   1678   new_len = (strlen (cp) + 1) * n_dup;
   1679 
   1680   sp = result = XNEWVEC (char, new_len);
   1681 
   1682   /* Global modifier characters mustn't be duplicated: skip if found.  */
   1683   if (*cp == '=' || *cp == '+' || *cp == '%')
   1684       *sp++ = *cp++;
   1685 
   1686   do
   1687     {
   1688       if ((ep = strchr (cp, ',')) != NULL)
   1689 	*ep++ = '\0';
   1690       len = strlen (cp);
   1691 
   1692       /* Copy a constraint N_DUP times.  */
   1693       for (i = 0; i < n_dup; i++, sp += len + 1)
   1694 	{
   1695 	  memcpy (sp, cp, len);
   1696 	  *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
   1697 	}
   1698 
   1699       cp = ep;
   1700     }
   1701   while (cp != NULL);
   1702 
   1703   return result;
   1704 }
   1705 
   1706 /* Alter the output of INSN whose pattern was modified by
   1707    DEFINE_SUBST.  We must replicate output strings according
   1708    to the new number of alternatives ALT in substituted pattern.
   1709    If ALT equals 1, output has one alternative or defined by C
   1710    code, then output is returned without any changes.  */
   1711 
   1712 static const char *
   1713 alter_output_for_subst_insn (rtx insn, int alt)
   1714 {
   1715   const char *insn_out, *old_out;
   1716   char *new_out, *cp;
   1717   size_t old_len, new_len;
   1718   int j;
   1719 
   1720   insn_out = XTMPL (insn, 3);
   1721 
   1722   if (alt < 2 || *insn_out != '@')
   1723     return insn_out;
   1724 
   1725   old_out = insn_out + 1;
   1726   while (ISSPACE (*old_out))
   1727     old_out++;
   1728   old_len = strlen (old_out);
   1729 
   1730   new_len = alt * (old_len + 1) + 1;
   1731 
   1732   new_out = XNEWVEC (char, new_len);
   1733   new_out[0] = '@';
   1734 
   1735   for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
   1736     {
   1737       memcpy (cp, old_out, old_len);
   1738       cp[old_len] = (j == alt - 1) ? '\0' : '\n';
   1739     }
   1740 
   1741   return new_out;
   1742 }
   1743 
   1744 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
   1745 
   1746 static void
   1747 process_one_cond_exec (class queue_elem *ce_elem)
   1748 {
   1749   class queue_elem *insn_elem;
   1750   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
   1751     {
   1752       int alternatives, max_operand;
   1753       rtx pred, insn, pattern, split;
   1754       char *new_name;
   1755       int i;
   1756 
   1757       if (! is_predicable (insn_elem))
   1758 	continue;
   1759 
   1760       alternatives = 1;
   1761       max_operand = -1;
   1762       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
   1763       max_operand += 1;
   1764 
   1765       if (XVECLEN (ce_elem->data, 0) != 1)
   1766 	{
   1767 	  error_at (ce_elem->loc, "too many patterns in predicate");
   1768 	  return;
   1769 	}
   1770 
   1771       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
   1772       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
   1773 				       ce_elem->loc);
   1774       if (pred == NULL)
   1775 	return;
   1776 
   1777       /* Construct a new pattern for the new insn.  */
   1778       insn = copy_rtx (insn_elem->data);
   1779       new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
   1780       sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
   1781       XSTR (insn, 0) = new_name;
   1782       pattern = rtx_alloc (COND_EXEC);
   1783       XEXP (pattern, 0) = pred;
   1784       XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
   1785       XVEC (insn, 1) = rtvec_alloc (1);
   1786       XVECEXP (insn, 1, 0) = pattern;
   1787 
   1788        if (XVEC (ce_elem->data, 3) != NULL)
   1789 	{
   1790 	  rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
   1791 	                                  + XVECLEN (ce_elem->data, 3));
   1792 	  int i = 0;
   1793 	  int j = 0;
   1794 	  for (i = 0; i < XVECLEN (insn, 4); i++)
   1795 	    RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
   1796 
   1797 	  for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
   1798 	    RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
   1799 
   1800 	  XVEC (insn, 4) = attributes;
   1801 	}
   1802 
   1803       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
   1804       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
   1805 					      alternatives, max_operand);
   1806       alter_attrs_for_insn (insn);
   1807 
   1808       /* Put the new pattern on the `other' list so that it
   1809 	 (a) is not reprocessed by other define_cond_exec patterns
   1810 	 (b) appears after all normal define_insn patterns.
   1811 
   1812 	 ??? B is debatable.  If one has normal insns that match
   1813 	 cond_exec patterns, they will be preferred over these
   1814 	 generated patterns.  Whether this matters in practice, or if
   1815 	 it's a good thing, or whether we should thread these new
   1816 	 patterns into the define_insn chain just after their generator
   1817 	 is something we'll have to experiment with.  */
   1818 
   1819       queue_pattern (insn, &other_tail, insn_elem->loc);
   1820 
   1821       if (!insn_elem->split)
   1822 	continue;
   1823 
   1824       /* If the original insn came from a define_insn_and_split,
   1825 	 generate a new split to handle the predicated insn.  */
   1826       split = copy_rtx (insn_elem->split->data);
   1827       /* Predicate the pattern matched by the split.  */
   1828       pattern = rtx_alloc (COND_EXEC);
   1829       XEXP (pattern, 0) = pred;
   1830       XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
   1831       XVEC (split, 0) = rtvec_alloc (1);
   1832       XVECEXP (split, 0, 0) = pattern;
   1833 
   1834       /* Predicate all of the insns generated by the split.  */
   1835       for (i = 0; i < XVECLEN (split, 2); i++)
   1836 	{
   1837 	  pattern = rtx_alloc (COND_EXEC);
   1838 	  XEXP (pattern, 0) = pred;
   1839 	  XEXP (pattern, 1) = XVECEXP (split, 2, i);
   1840 	  XVECEXP (split, 2, i) = pattern;
   1841 	}
   1842       /* Add the new split to the queue.  */
   1843       queue_pattern (split, &other_tail, insn_elem->split->loc);
   1844     }
   1845 }
   1846 
   1847 /* Try to apply define_substs to the given ELEM.
   1848    Only define_substs, specified via attributes would be applied.
   1849    If attribute, requiring define_subst, is set, but no define_subst
   1850    was applied, ELEM would be deleted.  */
   1851 
   1852 static void
   1853 process_substs_on_one_elem (class queue_elem *elem,
   1854 			    class queue_elem *queue)
   1855 {
   1856   class queue_elem *subst_elem;
   1857   int i, j, patterns_match;
   1858 
   1859   for (subst_elem = define_subst_queue;
   1860        subst_elem; subst_elem = subst_elem->next)
   1861     {
   1862       int alternatives, alternatives_subst;
   1863       rtx subst_pattern;
   1864       rtvec subst_pattern_vec;
   1865 
   1866       if (!has_subst_attribute (elem, subst_elem))
   1867 	continue;
   1868 
   1869       /* Compare original rtl-pattern from define_insn with input
   1870 	 pattern from define_subst.
   1871 	 Also, check if numbers of alternatives are the same in all
   1872 	 match_operands.  */
   1873       if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
   1874 	continue;
   1875       patterns_match = 1;
   1876       alternatives = -1;
   1877       alternatives_subst = -1;
   1878       for (j = 0; j < XVECLEN (elem->data, 1); j++)
   1879 	{
   1880 	  if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
   1881 				    XVECEXP (subst_elem->data, 1, j),
   1882 				    subst_elem->loc))
   1883 	    {
   1884 	      patterns_match = 0;
   1885 	      break;
   1886 	    }
   1887 
   1888 	  if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
   1889 					&alternatives, subst_elem->loc))
   1890 	    {
   1891 	      patterns_match = 0;
   1892 	      break;
   1893 	    }
   1894 	}
   1895 
   1896       /* Check if numbers of alternatives are the same in all
   1897 	 match_operands in output template of define_subst.  */
   1898       for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
   1899 	{
   1900 	  if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
   1901 					&alternatives_subst,
   1902 					subst_elem->loc))
   1903 	    {
   1904 	      patterns_match = 0;
   1905 	      break;
   1906 	    }
   1907 	}
   1908 
   1909       if (!patterns_match)
   1910 	continue;
   1911 
   1912       /* Clear array in which we save occupied indexes of operands.  */
   1913       memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
   1914 
   1915       /* Create a pattern, based on the output one from define_subst.  */
   1916       subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
   1917       for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
   1918 	{
   1919 	  subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
   1920 
   1921 	  /* Duplicate constraints in substitute-pattern.  */
   1922 	  subst_pattern = alter_constraints (subst_pattern, alternatives,
   1923 					     duplicate_each_alternative);
   1924 
   1925 	  subst_pattern = adjust_operands_numbers (subst_pattern);
   1926 
   1927 	  /* Substitute match_dup and match_op_dup in the new pattern and
   1928 	     duplicate constraints.  */
   1929 	  subst_pattern = subst_dup (subst_pattern, alternatives,
   1930 				     alternatives_subst);
   1931 
   1932 	  replace_duplicating_operands_in_pattern (subst_pattern);
   1933 
   1934 	  /* We don't need any constraints in DEFINE_EXPAND.  */
   1935 	  if (GET_CODE (elem->data) == DEFINE_EXPAND)
   1936 	    remove_constraints (subst_pattern);
   1937 
   1938 	  RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
   1939 	}
   1940       XVEC (elem->data, 1) = subst_pattern_vec;
   1941 
   1942       for (i = 0; i < MAX_OPERANDS; i++)
   1943 	  match_operand_entries_in_pattern[i] = NULL;
   1944 
   1945       if (GET_CODE (elem->data) == DEFINE_INSN)
   1946 	{
   1947 	  XTMPL (elem->data, 3) =
   1948 	    alter_output_for_subst_insn (elem->data, alternatives_subst);
   1949 	  alter_attrs_for_subst_insn (elem, alternatives_subst);
   1950 	}
   1951 
   1952       /* Recalculate condition, joining conditions from original and
   1953 	 DEFINE_SUBST input patterns.  */
   1954       XSTR (elem->data, 2)
   1955 	= rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
   1956 					     XSTR (elem->data, 2));
   1957       /* Mark that subst was applied by changing attribute from "yes"
   1958 	 to "no".  */
   1959       change_subst_attribute (elem, subst_elem, subst_false);
   1960     }
   1961 
   1962   /* If ELEM contains a subst attribute with value "yes", then we
   1963      expected that a subst would be applied, but it wasn't - so,
   1964      we need to remove that elementto avoid duplicating.  */
   1965   for (subst_elem = define_subst_queue;
   1966        subst_elem; subst_elem = subst_elem->next)
   1967     {
   1968       if (has_subst_attribute (elem, subst_elem))
   1969 	{
   1970 	  remove_from_queue (elem, &queue);
   1971 	  return;
   1972 	}
   1973     }
   1974 }
   1975 
   1976 /* This is a subroutine of mark_operands_used_in_match_dup.
   1977    This routine is marks all MATCH_OPERANDs inside PATTERN as occupied.  */
   1978 static void
   1979 mark_operands_from_match_dup (rtx pattern)
   1980 {
   1981   const char *fmt;
   1982   int i, j, len, opno;
   1983 
   1984   if (GET_CODE (pattern) == MATCH_OPERAND
   1985       || GET_CODE (pattern) == MATCH_OPERATOR
   1986       || GET_CODE (pattern) == MATCH_PARALLEL)
   1987     {
   1988       opno = XINT (pattern, 0);
   1989       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
   1990       used_operands_numbers [opno] = 1;
   1991     }
   1992   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
   1993   len = GET_RTX_LENGTH (GET_CODE (pattern));
   1994   for (i = 0; i < len; i++)
   1995     {
   1996       switch (fmt[i])
   1997 	{
   1998 	case 'e': case 'u':
   1999 	  mark_operands_from_match_dup (XEXP (pattern, i));
   2000 	  break;
   2001 	case 'E':
   2002 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   2003 	    mark_operands_from_match_dup (XVECEXP (pattern, i, j));
   2004 	  break;
   2005 	}
   2006     }
   2007 }
   2008 
   2009 /* This is a subroutine of adjust_operands_numbers.
   2010    It goes through all expressions in PATTERN and when MATCH_DUP is
   2011    met, all MATCH_OPERANDs inside it is marked as occupied.  The
   2012    process of marking is done by routin mark_operands_from_match_dup.  */
   2013 static void
   2014 mark_operands_used_in_match_dup (rtx pattern)
   2015 {
   2016   const char *fmt;
   2017   int i, j, len, opno;
   2018 
   2019   if (GET_CODE (pattern) == MATCH_DUP)
   2020     {
   2021       opno = XINT (pattern, 0);
   2022       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
   2023       mark_operands_from_match_dup (operand_data[opno]);
   2024       return;
   2025     }
   2026   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
   2027   len = GET_RTX_LENGTH (GET_CODE (pattern));
   2028   for (i = 0; i < len; i++)
   2029     {
   2030       switch (fmt[i])
   2031 	{
   2032 	case 'e': case 'u':
   2033 	  mark_operands_used_in_match_dup (XEXP (pattern, i));
   2034 	  break;
   2035 	case 'E':
   2036 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   2037 	    mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
   2038 	  break;
   2039 	}
   2040     }
   2041 }
   2042 
   2043 /* This is subroutine of renumerate_operands_in_pattern.
   2044    It finds first not-occupied operand-index.  */
   2045 static int
   2046 find_first_unused_number_of_operand ()
   2047 {
   2048   int i;
   2049   for (i = 0; i < MAX_OPERANDS; i++)
   2050     if (!used_operands_numbers[i])
   2051       return i;
   2052   return MAX_OPERANDS;
   2053 }
   2054 
   2055 /* This is subroutine of adjust_operands_numbers.
   2056    It visits all expressions in PATTERN and assigns not-occupied
   2057    operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
   2058    PATTERN.  */
   2059 static void
   2060 renumerate_operands_in_pattern (rtx pattern)
   2061 {
   2062   const char *fmt;
   2063   enum rtx_code code;
   2064   int i, j, len, new_opno;
   2065   code = GET_CODE (pattern);
   2066 
   2067   if (code == MATCH_OPERAND
   2068       || code == MATCH_OPERATOR)
   2069     {
   2070       new_opno = find_first_unused_number_of_operand ();
   2071       gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
   2072       XINT (pattern, 0) = new_opno;
   2073       used_operands_numbers [new_opno] = 1;
   2074     }
   2075 
   2076   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
   2077   len = GET_RTX_LENGTH (GET_CODE (pattern));
   2078   for (i = 0; i < len; i++)
   2079     {
   2080       switch (fmt[i])
   2081 	{
   2082 	case 'e': case 'u':
   2083 	  renumerate_operands_in_pattern (XEXP (pattern, i));
   2084 	  break;
   2085 	case 'E':
   2086 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   2087 	    renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
   2088 	  break;
   2089 	}
   2090     }
   2091 }
   2092 
   2093 /* If output pattern of define_subst contains MATCH_DUP, then this
   2094    expression would be replaced with the pattern, matched with
   2095    MATCH_OPERAND from input pattern.  This pattern could contain any
   2096    number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
   2097    that a MATCH_OPERAND from output_pattern (if any) would have the
   2098    same number, as MATCH_OPERAND from copied pattern.  To avoid such
   2099    indexes overlapping, we assign new indexes to MATCH_OPERANDs,
   2100    laying in the output pattern outside of MATCH_DUPs.  */
   2101 static rtx
   2102 adjust_operands_numbers (rtx pattern)
   2103 {
   2104   mark_operands_used_in_match_dup (pattern);
   2105 
   2106   renumerate_operands_in_pattern (pattern);
   2107 
   2108   return pattern;
   2109 }
   2110 
   2111 /* Generate RTL expression
   2112    (match_dup OPNO)
   2113    */
   2114 static rtx
   2115 generate_match_dup (int opno)
   2116 {
   2117   rtx return_rtx = rtx_alloc (MATCH_DUP);
   2118   PUT_CODE (return_rtx, MATCH_DUP);
   2119   XINT (return_rtx, 0) = opno;
   2120   return return_rtx;
   2121 }
   2122 
   2123 /* This routine checks all match_operands in PATTERN and if some of
   2124    have the same index, it replaces all of them except the first one  to
   2125    match_dup.
   2126    Usually, match_operands with the same indexes are forbidden, but
   2127    after define_subst copy an RTL-expression from original template,
   2128    indexes of existed and just-copied match_operands could coincide.
   2129    To fix it, we replace one of them with match_dup.  */
   2130 static rtx
   2131 replace_duplicating_operands_in_pattern (rtx pattern)
   2132 {
   2133   const char *fmt;
   2134   int i, j, len, opno;
   2135   rtx mdup;
   2136 
   2137   if (GET_CODE (pattern) == MATCH_OPERAND)
   2138     {
   2139       opno = XINT (pattern, 0);
   2140       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
   2141       if (match_operand_entries_in_pattern[opno] == NULL)
   2142 	{
   2143 	  match_operand_entries_in_pattern[opno] = pattern;
   2144 	  return NULL;
   2145 	}
   2146       else
   2147 	{
   2148 	  /* Compare predicates before replacing with match_dup.  */
   2149 	  if (strcmp (XSTR (pattern, 1),
   2150 		      XSTR (match_operand_entries_in_pattern[opno], 1)))
   2151 	    {
   2152 	      error ("duplicated match_operands with different predicates were"
   2153 		     " found.");
   2154 	      return NULL;
   2155 	    }
   2156 	  return generate_match_dup (opno);
   2157 	}
   2158     }
   2159   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
   2160   len = GET_RTX_LENGTH (GET_CODE (pattern));
   2161   for (i = 0; i < len; i++)
   2162     {
   2163       switch (fmt[i])
   2164 	{
   2165 	case 'e': case 'u':
   2166 	  mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
   2167 	  if (mdup)
   2168 	    XEXP (pattern, i) = mdup;
   2169 	  break;
   2170 	case 'E':
   2171 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   2172 	    {
   2173 	      mdup =
   2174 		replace_duplicating_operands_in_pattern (XVECEXP
   2175 							 (pattern, i, j));
   2176 	      if (mdup)
   2177 		XVECEXP (pattern, i, j) = mdup;
   2178 	    }
   2179 	  break;
   2180 	}
   2181     }
   2182   return NULL;
   2183 }
   2184 
   2185 /* The routine modifies given input PATTERN of define_subst, replacing
   2186    MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
   2187    pattern, whose operands are stored in OPERAND_DATA array.
   2188    It also duplicates constraints in operands - constraints from
   2189    define_insn operands are duplicated N_SUBST_ALT times, constraints
   2190    from define_subst operands are duplicated N_ALT times.
   2191    After the duplication, returned output rtl-pattern contains every
   2192    combination of input constraints Vs constraints from define_subst
   2193    output.  */
   2194 static rtx
   2195 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
   2196 {
   2197   const char *fmt;
   2198   enum rtx_code code;
   2199   int i, j, len, opno;
   2200 
   2201   code = GET_CODE (pattern);
   2202   switch (code)
   2203     {
   2204     case MATCH_DUP:
   2205     case MATCH_OP_DUP:
   2206       opno = XINT (pattern, 0);
   2207 
   2208       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
   2209 
   2210       if (operand_data[opno])
   2211 	{
   2212 	  pattern = copy_rtx (operand_data[opno]);
   2213 
   2214 	  /* Duplicate constraints.  */
   2215 	  pattern = alter_constraints (pattern, n_subst_alt,
   2216 				       duplicate_alternatives);
   2217 	}
   2218       break;
   2219 
   2220     default:
   2221       break;
   2222     }
   2223 
   2224   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
   2225   len = GET_RTX_LENGTH (GET_CODE (pattern));
   2226   for (i = 0; i < len; i++)
   2227     {
   2228       switch (fmt[i])
   2229 	{
   2230 	case 'e': case 'u':
   2231 	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
   2232 	    XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
   2233 					   n_alt, n_subst_alt);
   2234 	  break;
   2235 	case 'V':
   2236 	  if (XVEC (pattern, i) == NULL)
   2237 	    break;
   2238 	  /* FALLTHRU */
   2239 	case 'E':
   2240 	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
   2241 	    for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
   2242 	      XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
   2243 						   n_alt, n_subst_alt);
   2244 	  break;
   2245 
   2246 	case 'r': case 'p': case 'i': case 'w':
   2247 	case '0': case 's': case 'S': case 'T':
   2248 	  break;
   2249 
   2250 	default:
   2251 	  gcc_unreachable ();
   2252 	}
   2253     }
   2254   return pattern;
   2255 }
   2256 
   2257 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
   2258    patterns appropriately.  */
   2259 
   2260 static void
   2261 process_define_cond_exec (void)
   2262 {
   2263   class queue_elem *elem;
   2264 
   2265   identify_predicable_attribute ();
   2266   if (have_error)
   2267     return;
   2268 
   2269   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
   2270     process_one_cond_exec (elem);
   2271 }
   2272 
   2273 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
   2274    DEFINE_EXPAND patterns appropriately.  */
   2275 
   2276 static void
   2277 process_define_subst (void)
   2278 {
   2279   class queue_elem *elem, *elem_attr;
   2280 
   2281   /* Check if each define_subst has corresponding define_subst_attr.  */
   2282   for (elem = define_subst_queue; elem ; elem = elem->next)
   2283     {
   2284       for (elem_attr = define_subst_attr_queue;
   2285 	   elem_attr;
   2286 	   elem_attr = elem_attr->next)
   2287 	if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
   2288 	    goto found;
   2289 
   2290       error_at (elem->loc,
   2291 		"%s: `define_subst' must have at least one "
   2292 		"corresponding `define_subst_attr'",
   2293 		XSTR (elem->data, 0));
   2294       return;
   2295 
   2296       found:
   2297 	continue;
   2298     }
   2299 
   2300   for (elem = define_insn_queue; elem ; elem = elem->next)
   2301     process_substs_on_one_elem (elem, define_insn_queue);
   2302   for (elem = other_queue; elem ; elem = elem->next)
   2303     {
   2304       if (GET_CODE (elem->data) != DEFINE_EXPAND)
   2305 	continue;
   2306       process_substs_on_one_elem (elem, other_queue);
   2307     }
   2308 }
   2309 
   2310 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
   2312    the top-level elements.  */
   2313 
   2314 class gen_reader : public rtx_reader
   2315 {
   2316  public:
   2317   gen_reader () : rtx_reader (false) {}
   2318   void handle_unknown_directive (file_location, const char *);
   2319 };
   2320 
   2321 void
   2322 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
   2323 {
   2324   auto_vec<rtx, 32> subrtxs;
   2325   if (!read_rtx (rtx_name, &subrtxs))
   2326     return;
   2327 
   2328   rtx x;
   2329   unsigned int i;
   2330   FOR_EACH_VEC_ELT (subrtxs, i, x)
   2331     process_rtx (x, loc);
   2332 }
   2333 
   2334 /* Add mnemonic STR with length LEN to the mnemonic hash table
   2335    MNEMONIC_HTAB.  A trailing zero end character is appended to STR
   2336    and a permanent heap copy of STR is created.  */
   2337 
   2338 static void
   2339 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
   2340 {
   2341   char *new_str;
   2342   void **slot;
   2343   char *str_zero = (char*)alloca (len + 1);
   2344 
   2345   memcpy (str_zero, str, len);
   2346   str_zero[len] = '\0';
   2347 
   2348   slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
   2349 
   2350   if (*slot)
   2351     return;
   2352 
   2353   /* Not found; create a permanent copy and add it to the hash table.  */
   2354   new_str = XNEWVAR (char, len + 1);
   2355   memcpy (new_str, str_zero, len + 1);
   2356   *slot = new_str;
   2357 }
   2358 
   2359 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
   2360    table in MNEMONIC_HTAB.
   2361 
   2362    The mnemonics cannot be found if they are emitted using C code.
   2363 
   2364    If a mnemonic string contains ';' or a newline the string assumed
   2365    to consist of more than a single instruction.  The attribute value
   2366    will then be set to the user defined default value.  */
   2367 
   2368 static void
   2369 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
   2370 {
   2371   const char *template_code, *cp;
   2372   int i;
   2373   int vec_len;
   2374   rtx set_attr;
   2375   char *attr_name;
   2376   rtvec new_vec;
   2377   struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
   2378 
   2379   template_code = XTMPL (insn, 3);
   2380 
   2381   /* Skip patterns which use C code to emit the template.  */
   2382   if (template_code[0] == '*')
   2383     return;
   2384 
   2385   if (template_code[0] == '@')
   2386     cp = &template_code[1];
   2387   else
   2388     cp = &template_code[0];
   2389 
   2390   for (i = 0; *cp; )
   2391     {
   2392       const char *ep, *sp;
   2393       size_t size = 0;
   2394 
   2395       while (ISSPACE (*cp))
   2396 	cp++;
   2397 
   2398       for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
   2399 	if (!ISSPACE (*ep))
   2400 	  sp = ep + 1;
   2401 
   2402       if (i > 0)
   2403 	obstack_1grow (string_obstack, ',');
   2404 
   2405       while (cp < sp && ((*cp >= '0' && *cp <= '9')
   2406 			 || (*cp >= 'a' && *cp <= 'z')))
   2407 
   2408 	{
   2409 	  obstack_1grow (string_obstack, *cp);
   2410 	  cp++;
   2411 	  size++;
   2412 	}
   2413 
   2414       while (cp < sp)
   2415 	{
   2416 	  if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
   2417 	    {
   2418 	      /* Don't set a value if there are more than one
   2419 		 instruction in the string.  */
   2420 	      obstack_blank_fast (string_obstack, -size);
   2421 	      size = 0;
   2422 
   2423 	      cp = sp;
   2424 	      break;
   2425 	    }
   2426 	  cp++;
   2427 	}
   2428       if (size == 0)
   2429 	obstack_1grow (string_obstack, '*');
   2430       else
   2431 	add_mnemonic_string (mnemonic_htab,
   2432 			     (char *) obstack_next_free (string_obstack) - size,
   2433 			     size);
   2434       i++;
   2435     }
   2436 
   2437   /* An insn definition might emit an empty string.  */
   2438   if (obstack_object_size (string_obstack) == 0)
   2439     return;
   2440 
   2441   obstack_1grow (string_obstack, '\0');
   2442 
   2443   set_attr = rtx_alloc (SET_ATTR);
   2444   XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
   2445   attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
   2446   strcpy (attr_name, MNEMONIC_ATTR_NAME);
   2447   XSTR (set_attr, 0) = attr_name;
   2448 
   2449   if (!XVEC (insn, 4))
   2450     vec_len = 0;
   2451   else
   2452     vec_len = XVECLEN (insn, 4);
   2453 
   2454   new_vec = rtvec_alloc (vec_len + 1);
   2455   for (i = 0; i < vec_len; i++)
   2456     RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
   2457   RTVEC_ELT (new_vec, vec_len) = set_attr;
   2458   XVEC (insn, 4) = new_vec;
   2459 }
   2460 
   2461 /* This function is called for the elements in the mnemonic hashtable
   2462    and generates a comma separated list of the mnemonics.  */
   2463 
   2464 static int
   2465 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
   2466 {
   2467   struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
   2468 
   2469   obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
   2470   obstack_1grow (string_obstack, ',');
   2471   return 1;
   2472 }
   2473 
   2474 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
   2475    insn definition in case the back end requests it by defining the
   2476    mnemonic attribute.  The values for the attribute will be extracted
   2477    from the output patterns of the insn definitions as far as
   2478    possible.  */
   2479 
   2480 static void
   2481 gen_mnemonic_attr (void)
   2482 {
   2483   class queue_elem *elem;
   2484   rtx mnemonic_attr = NULL;
   2485   htab_t mnemonic_htab;
   2486   const char *str, *p;
   2487   int i;
   2488   struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
   2489 
   2490   if (have_error)
   2491     return;
   2492 
   2493   /* Look for the DEFINE_ATTR for `mnemonic'.  */
   2494   for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
   2495     if (GET_CODE (elem->data) == DEFINE_ATTR
   2496 	&& strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
   2497       {
   2498 	mnemonic_attr = elem->data;
   2499 	break;
   2500       }
   2501 
   2502   /* A (define_attr "mnemonic" "...") indicates that the back-end
   2503      wants a mnemonic attribute to be generated.  */
   2504   if (!mnemonic_attr)
   2505     return;
   2506 
   2507   mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
   2508 				     htab_eq_string, 0, xcalloc, free);
   2509 
   2510   for (elem = define_insn_queue; elem; elem = elem->next)
   2511     {
   2512       rtx insn = elem->data;
   2513       bool found = false;
   2514 
   2515       /* Check if the insn definition already has
   2516 	 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...).  */
   2517       if (XVEC (insn, 4))
   2518  	for (i = 0; i < XVECLEN (insn, 4); i++)
   2519 	  {
   2520 	    rtx set_attr = XVECEXP (insn, 4, i);
   2521 
   2522 	    switch (GET_CODE (set_attr))
   2523 	      {
   2524 	      case SET_ATTR:
   2525 	      case SET_ATTR_ALTERNATIVE:
   2526 		if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
   2527 		  found = true;
   2528 		break;
   2529 	      case SET:
   2530 		if (GET_CODE (SET_DEST (set_attr)) == ATTR
   2531 		    && strcmp (XSTR (SET_DEST (set_attr), 0),
   2532 			       MNEMONIC_ATTR_NAME) == 0)
   2533 		  found = true;
   2534 		break;
   2535 	      default:
   2536 		break;
   2537 	      }
   2538 	  }
   2539 
   2540       if (!found)
   2541 	gen_mnemonic_setattr (mnemonic_htab, insn);
   2542     }
   2543 
   2544   /* Add the user defined values to the hash table.  */
   2545   str = XSTR (mnemonic_attr, 1);
   2546   while ((p = scan_comma_elt (&str)) != NULL)
   2547     add_mnemonic_string (mnemonic_htab, p, str - p);
   2548 
   2549   htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
   2550 
   2551   /* Replace the last ',' with the zero end character.  */
   2552   *((char *) obstack_next_free (string_obstack) - 1) = '\0';
   2553   XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
   2554 }
   2555 
   2556 /* Check if there are DEFINE_ATTRs with the same name.  */
   2557 static void
   2558 check_define_attr_duplicates ()
   2559 {
   2560   class queue_elem *elem;
   2561   htab_t attr_htab;
   2562   char * attr_name;
   2563   void **slot;
   2564 
   2565   attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
   2566 
   2567   for (elem = define_attr_queue; elem; elem = elem->next)
   2568     {
   2569       attr_name = xstrdup (XSTR (elem->data, 0));
   2570 
   2571       slot = htab_find_slot (attr_htab, attr_name, INSERT);
   2572 
   2573       /* Duplicate.  */
   2574       if (*slot)
   2575 	{
   2576 	  error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
   2577 	  htab_delete (attr_htab);
   2578 	  return;
   2579 	}
   2580 
   2581       *slot = attr_name;
   2582     }
   2583 
   2584   htab_delete (attr_htab);
   2585 }
   2586 
   2587 /* The entry point for initializing the reader.  */
   2588 
   2589 rtx_reader *
   2590 init_rtx_reader_args_cb (int argc, const char **argv,
   2591 			 bool (*parse_opt) (const char *))
   2592 {
   2593   /* Prepare to read input.  */
   2594   condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
   2595   init_predicate_table ();
   2596   obstack_init (rtl_obstack);
   2597 
   2598   /* Start at 1, to make 0 available for CODE_FOR_nothing.  */
   2599   insn_sequence_num = 1;
   2600 
   2601   /* These sequences are not used as indices, so can start at 1 also.  */
   2602   split_sequence_num = 1;
   2603   peephole2_sequence_num = 1;
   2604 
   2605   gen_reader *reader = new gen_reader ();
   2606   reader->read_md_files (argc, argv, parse_opt);
   2607 
   2608   if (define_attr_queue != NULL)
   2609     check_define_attr_duplicates ();
   2610 
   2611   /* Process define_cond_exec patterns.  */
   2612   if (define_cond_exec_queue != NULL)
   2613     process_define_cond_exec ();
   2614 
   2615   /* Process define_subst patterns.  */
   2616   if (define_subst_queue != NULL)
   2617     process_define_subst ();
   2618 
   2619   if (define_attr_queue != NULL)
   2620     gen_mnemonic_attr ();
   2621 
   2622   if (have_error)
   2623     {
   2624       delete reader;
   2625       return NULL;
   2626     }
   2627 
   2628   return reader;
   2629 }
   2630 
   2631 /* Programs that don't have their own options can use this entry point
   2632    instead.  */
   2633 rtx_reader *
   2634 init_rtx_reader_args (int argc, const char **argv)
   2635 {
   2636   return init_rtx_reader_args_cb (argc, argv, 0);
   2637 }
   2638 
   2639 /* Try to read a single rtx from the file.  Return true on success,
   2641    describing it in *INFO.  */
   2642 
   2643 bool
   2644 read_md_rtx (md_rtx_info *info)
   2645 {
   2646   int truth, *counter;
   2647   rtx def;
   2648 
   2649   /* Discard insn patterns which we know can never match (because
   2650      their C test is provably always false).  If insn_elision is
   2651      false, our caller needs to see all the patterns.  Note that the
   2652      elided patterns are never counted by the sequence numbering; it
   2653      is the caller's responsibility, when insn_elision is false, not
   2654      to use elided pattern numbers for anything.  */
   2655   do
   2656     {
   2657       class queue_elem **queue, *elem;
   2658 
   2659       /* Read all patterns from a given queue before moving on to the next.  */
   2660       if (define_attr_queue != NULL)
   2661 	queue = &define_attr_queue;
   2662       else if (define_pred_queue != NULL)
   2663 	queue = &define_pred_queue;
   2664       else if (define_insn_queue != NULL)
   2665 	queue = &define_insn_queue;
   2666       else if (other_queue != NULL)
   2667 	queue = &other_queue;
   2668       else
   2669 	return false;
   2670 
   2671       elem = *queue;
   2672       *queue = elem->next;
   2673       def = elem->data;
   2674       info->def = def;
   2675       info->loc = elem->loc;
   2676       free (elem);
   2677 
   2678       truth = maybe_eval_c_test (get_c_test (def));
   2679     }
   2680   while (truth == 0 && insn_elision);
   2681 
   2682   /* Perform code-specific processing and pick the appropriate sequence
   2683      number counter.  */
   2684   switch (GET_CODE (def))
   2685     {
   2686     case DEFINE_INSN:
   2687     case DEFINE_EXPAND:
   2688       /* insn_sequence_num is used here so the name table will match caller's
   2689 	 idea of insn numbering, whether or not elision is active.  */
   2690       record_insn_name (insn_sequence_num, XSTR (def, 0));
   2691 
   2692       /* Fall through.  */
   2693     case DEFINE_PEEPHOLE:
   2694       counter = &insn_sequence_num;
   2695       break;
   2696 
   2697     case DEFINE_SPLIT:
   2698       counter = &split_sequence_num;
   2699       break;
   2700 
   2701     case DEFINE_PEEPHOLE2:
   2702       counter = &peephole2_sequence_num;
   2703       break;
   2704 
   2705     default:
   2706       counter = NULL;
   2707       break;
   2708     }
   2709 
   2710   if (counter)
   2711     {
   2712       info->index = *counter;
   2713       if (truth != 0)
   2714 	*counter += 1;
   2715     }
   2716   else
   2717     info->index = -1;
   2718 
   2719   if (!rtx_locs)
   2720     rtx_locs = new hash_map <rtx, file_location>;
   2721   rtx_locs->put (info->def, info->loc);
   2722 
   2723   return true;
   2724 }
   2725 
   2726 /* Return the file location of DEFINE_* rtx X, which was previously
   2727    returned by read_md_rtx.  */
   2728 file_location
   2729 get_file_location (rtx x)
   2730 {
   2731   gcc_assert (rtx_locs);
   2732   file_location *entry = rtx_locs->get (x);
   2733   gcc_assert (entry);
   2734   return *entry;
   2735 }
   2736 
   2737 /* Return the number of possible INSN_CODEs.  Only meaningful once the
   2738    whole file has been processed.  */
   2739 unsigned int
   2740 get_num_insn_codes ()
   2741 {
   2742   return insn_sequence_num;
   2743 }
   2744 
   2745 /* Return the C test that says whether definition rtx DEF can be used,
   2746    or "" if it can be used unconditionally.  */
   2747 
   2748 const char *
   2749 get_c_test (rtx x)
   2750 {
   2751   switch (GET_CODE (x))
   2752     {
   2753     case DEFINE_INSN:
   2754     case DEFINE_EXPAND:
   2755     case DEFINE_SUBST:
   2756       return XSTR (x, 2);
   2757 
   2758     case DEFINE_SPLIT:
   2759     case DEFINE_PEEPHOLE:
   2760     case DEFINE_PEEPHOLE2:
   2761       return XSTR (x, 1);
   2762 
   2763     default:
   2764       return "";
   2765     }
   2766 }
   2767 
   2768 /* Helper functions for insn elision.  */
   2769 
   2770 /* Compute a hash function of a c_test structure, which is keyed
   2771    by its ->expr field.  */
   2772 hashval_t
   2773 hash_c_test (const void *x)
   2774 {
   2775   const struct c_test *a = (const struct c_test *) x;
   2776   const unsigned char *base, *s = (const unsigned char *) a->expr;
   2777   hashval_t hash;
   2778   unsigned char c;
   2779   unsigned int len;
   2780 
   2781   base = s;
   2782   hash = 0;
   2783 
   2784   while ((c = *s++) != '\0')
   2785     {
   2786       hash += c + (c << 17);
   2787       hash ^= hash >> 2;
   2788     }
   2789 
   2790   len = s - base;
   2791   hash += len + (len << 17);
   2792   hash ^= hash >> 2;
   2793 
   2794   return hash;
   2795 }
   2796 
   2797 /* Compare two c_test expression structures.  */
   2798 int
   2799 cmp_c_test (const void *x, const void *y)
   2800 {
   2801   const struct c_test *a = (const struct c_test *) x;
   2802   const struct c_test *b = (const struct c_test *) y;
   2803 
   2804   return !strcmp (a->expr, b->expr);
   2805 }
   2806 
   2807 /* Given a string representing a C test expression, look it up in the
   2808    condition_table and report whether or not its value is known
   2809    at compile time.  Returns a tristate: 1 for known true, 0 for
   2810    known false, -1 for unknown.  */
   2811 int
   2812 maybe_eval_c_test (const char *expr)
   2813 {
   2814   const struct c_test *test;
   2815   struct c_test dummy;
   2816 
   2817   if (expr[0] == 0)
   2818     return 1;
   2819 
   2820   dummy.expr = expr;
   2821   test = (const struct c_test *)htab_find (condition_table, &dummy);
   2822   if (!test)
   2823     return -1;
   2824   return test->value;
   2825 }
   2826 
   2827 /* Record the C test expression EXPR in the condition_table, with
   2828    value VAL.  Duplicates clobber previous entries.  */
   2829 
   2830 void
   2831 add_c_test (const char *expr, int value)
   2832 {
   2833   struct c_test *test;
   2834 
   2835   if (expr[0] == 0)
   2836     return;
   2837 
   2838   test = XNEW (struct c_test);
   2839   test->expr = expr;
   2840   test->value = value;
   2841 
   2842   *(htab_find_slot (condition_table, test, INSERT)) = test;
   2843 }
   2844 
   2845 /* For every C test, call CALLBACK with two arguments: a pointer to
   2846    the condition structure and INFO.  Stops when CALLBACK returns zero.  */
   2847 void
   2848 traverse_c_tests (htab_trav callback, void *info)
   2849 {
   2850   if (condition_table)
   2851     htab_traverse (condition_table, callback, info);
   2852 }
   2853 
   2854 /* Helper functions for define_predicate and define_special_predicate
   2855    processing.  Shared between genrecog.cc and genpreds.cc.  */
   2856 
   2857 static htab_t predicate_table;
   2858 struct pred_data *first_predicate;
   2859 static struct pred_data **last_predicate = &first_predicate;
   2860 
   2861 static hashval_t
   2862 hash_struct_pred_data (const void *ptr)
   2863 {
   2864   return htab_hash_string (((const struct pred_data *)ptr)->name);
   2865 }
   2866 
   2867 static int
   2868 eq_struct_pred_data (const void *a, const void *b)
   2869 {
   2870   return !strcmp (((const struct pred_data *)a)->name,
   2871 		  ((const struct pred_data *)b)->name);
   2872 }
   2873 
   2874 struct pred_data *
   2875 lookup_predicate (const char *name)
   2876 {
   2877   struct pred_data key;
   2878   key.name = name;
   2879   return (struct pred_data *) htab_find (predicate_table, &key);
   2880 }
   2881 
   2882 /* Record that predicate PRED can accept CODE.  */
   2883 
   2884 void
   2885 add_predicate_code (struct pred_data *pred, enum rtx_code code)
   2886 {
   2887   if (!pred->codes[code])
   2888     {
   2889       pred->num_codes++;
   2890       pred->codes[code] = true;
   2891 
   2892       if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
   2893 	pred->allows_non_const = true;
   2894 
   2895       if (code != REG
   2896 	  && code != SUBREG
   2897 	  && code != MEM
   2898 	  && code != CONCAT
   2899 	  && code != PARALLEL
   2900 	  && code != STRICT_LOW_PART
   2901 	  && code != ZERO_EXTRACT
   2902 	  && code != SCRATCH)
   2903 	pred->allows_non_lvalue = true;
   2904 
   2905       if (pred->num_codes == 1)
   2906 	pred->singleton = code;
   2907       else if (pred->num_codes == 2)
   2908 	pred->singleton = UNKNOWN;
   2909     }
   2910 }
   2911 
   2912 void
   2913 add_predicate (struct pred_data *pred)
   2914 {
   2915   void **slot = htab_find_slot (predicate_table, pred, INSERT);
   2916   if (*slot)
   2917     {
   2918       error ("duplicate predicate definition for '%s'", pred->name);
   2919       return;
   2920     }
   2921   *slot = pred;
   2922   *last_predicate = pred;
   2923   last_predicate = &pred->next;
   2924 }
   2925 
   2926 /* This array gives the initial content of the predicate table.  It
   2927    has entries for all predicates defined in recog.cc.  */
   2928 
   2929 struct std_pred_table
   2930 {
   2931   const char *name;
   2932   bool special;
   2933   bool allows_const_p;
   2934   RTX_CODE codes[NUM_RTX_CODE];
   2935 };
   2936 
   2937 static const struct std_pred_table std_preds[] = {
   2938   {"general_operand", false, true, {SUBREG, REG, MEM}},
   2939   {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
   2940 				   ZERO_EXTEND, SIGN_EXTEND, AND}},
   2941   {"register_operand", false, false, {SUBREG, REG}},
   2942   {"pmode_register_operand", true, false, {SUBREG, REG}},
   2943   {"scratch_operand", false, false, {SCRATCH, REG}},
   2944   {"immediate_operand", false, true, {UNKNOWN}},
   2945   {"const_int_operand", false, false, {CONST_INT}},
   2946 #if TARGET_SUPPORTS_WIDE_INT
   2947   {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
   2948   {"const_double_operand", false, false, {CONST_DOUBLE}},
   2949 #else
   2950   {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
   2951 #endif
   2952   {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
   2953   {"nonmemory_operand", false, true, {SUBREG, REG}},
   2954   {"push_operand", false, false, {MEM}},
   2955   {"pop_operand", false, false, {MEM}},
   2956   {"memory_operand", false, false, {SUBREG, MEM}},
   2957   {"indirect_operand", false, false, {SUBREG, MEM}},
   2958   {"ordered_comparison_operator", false, false, {EQ, NE,
   2959 						 LE, LT, GE, GT,
   2960 						 LEU, LTU, GEU, GTU}},
   2961   {"comparison_operator", false, false, {EQ, NE,
   2962 					 LE, LT, GE, GT,
   2963 					 LEU, LTU, GEU, GTU,
   2964 					 UNORDERED, ORDERED,
   2965 					 UNEQ, UNGE, UNGT,
   2966 					 UNLE, UNLT, LTGT}}
   2967 };
   2968 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
   2969 
   2970 /* Initialize the table of predicate definitions, starting with
   2971    the information we have on generic predicates.  */
   2972 
   2973 static void
   2974 init_predicate_table (void)
   2975 {
   2976   size_t i, j;
   2977   struct pred_data *pred;
   2978 
   2979   predicate_table = htab_create_alloc (37, hash_struct_pred_data,
   2980 				       eq_struct_pred_data, 0,
   2981 				       xcalloc, free);
   2982 
   2983   for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
   2984     {
   2985       pred = XCNEW (struct pred_data);
   2986       pred->name = std_preds[i].name;
   2987       pred->special = std_preds[i].special;
   2988 
   2989       for (j = 0; std_preds[i].codes[j] != 0; j++)
   2990 	add_predicate_code (pred, std_preds[i].codes[j]);
   2991 
   2992       if (std_preds[i].allows_const_p)
   2993 	for (j = 0; j < NUM_RTX_CODE; j++)
   2994 	  if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
   2995 	    add_predicate_code (pred, (enum rtx_code) j);
   2996 
   2997       add_predicate (pred);
   2998     }
   2999 }
   3000 
   3001 /* These functions allow linkage with print-rtl.cc.  Also, some generators
   3003    like to annotate their output with insn names.  */
   3004 
   3005 /* Holds an array of names indexed by insn_code_number.  */
   3006 static char **insn_name_ptr = 0;
   3007 static int insn_name_ptr_size = 0;
   3008 
   3009 const char *
   3010 get_insn_name (int code)
   3011 {
   3012   if (code < insn_name_ptr_size)
   3013     return insn_name_ptr[code];
   3014   else
   3015     return NULL;
   3016 }
   3017 
   3018 static void
   3019 record_insn_name (int code, const char *name)
   3020 {
   3021   static const char *last_real_name = "insn";
   3022   static int last_real_code = 0;
   3023   char *new_name;
   3024 
   3025   if (insn_name_ptr_size <= code)
   3026     {
   3027       int new_size;
   3028       new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
   3029       insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
   3030       memset (insn_name_ptr + insn_name_ptr_size, 0,
   3031 	      sizeof (char *) * (new_size - insn_name_ptr_size));
   3032       insn_name_ptr_size = new_size;
   3033     }
   3034 
   3035   if (!name || name[0] == '\0')
   3036     {
   3037       new_name = XNEWVAR (char, strlen (last_real_name) + 10);
   3038       sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
   3039     }
   3040   else
   3041     {
   3042       last_real_name = new_name = xstrdup (name);
   3043       last_real_code = code;
   3044     }
   3045 
   3046   insn_name_ptr[code] = new_name;
   3047 }
   3048 
   3049 /* Make STATS describe the operands that appear in rtx X.  */
   3051 
   3052 static void
   3053 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
   3054 {
   3055   RTX_CODE code;
   3056   int i;
   3057   int len;
   3058   const char *fmt;
   3059 
   3060   if (x == NULL_RTX)
   3061     return;
   3062 
   3063   code = GET_CODE (x);
   3064   switch (code)
   3065     {
   3066     case MATCH_OPERAND:
   3067     case MATCH_OPERATOR:
   3068     case MATCH_PARALLEL:
   3069       stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
   3070       break;
   3071 
   3072     case MATCH_DUP:
   3073     case MATCH_OP_DUP:
   3074     case MATCH_PAR_DUP:
   3075       stats->num_dups++;
   3076       stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
   3077       break;
   3078 
   3079     case MATCH_SCRATCH:
   3080       if (stats->min_scratch_opno == -1)
   3081 	stats->min_scratch_opno = XINT (x, 0);
   3082       else
   3083 	stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
   3084       stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
   3085       break;
   3086 
   3087     default:
   3088       break;
   3089     }
   3090 
   3091   fmt = GET_RTX_FORMAT (code);
   3092   len = GET_RTX_LENGTH (code);
   3093   for (i = 0; i < len; i++)
   3094     {
   3095       if (fmt[i] == 'e' || fmt[i] == 'u')
   3096 	get_pattern_stats_1 (stats, XEXP (x, i));
   3097       else if (fmt[i] == 'E')
   3098 	{
   3099 	  int j;
   3100 	  for (j = 0; j < XVECLEN (x, i); j++)
   3101 	    get_pattern_stats_1 (stats, XVECEXP (x, i, j));
   3102 	}
   3103     }
   3104 }
   3105 
   3106 /* Make STATS describe the operands that appear in instruction pattern
   3107    PATTERN.  */
   3108 
   3109 void
   3110 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
   3111 {
   3112   int i, len;
   3113 
   3114   stats->max_opno = -1;
   3115   stats->max_dup_opno = -1;
   3116   stats->min_scratch_opno = -1;
   3117   stats->max_scratch_opno = -1;
   3118   stats->num_dups = 0;
   3119 
   3120   len = GET_NUM_ELEM (pattern);
   3121   for (i = 0; i < len; i++)
   3122     get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
   3123 
   3124   stats->num_generator_args = stats->max_opno + 1;
   3125   stats->num_insn_operands = MAX (stats->max_opno,
   3126 				  stats->max_scratch_opno) + 1;
   3127   stats->num_operand_vars = MAX (stats->max_opno,
   3128 				  MAX (stats->max_dup_opno,
   3129 				       stats->max_scratch_opno)) + 1;
   3130 }
   3131 
   3132 /* Return the emit_* function that should be used for pattern X, or NULL
   3133    if we can't pick a particular type at compile time and should instead
   3134    fall back to "emit".  */
   3135 
   3136 const char *
   3137 get_emit_function (rtx x)
   3138 {
   3139   switch (classify_insn (x))
   3140     {
   3141     case INSN:
   3142       return "emit_insn";
   3143 
   3144     case CALL_INSN:
   3145       return "emit_call_insn";
   3146 
   3147     case JUMP_INSN:
   3148       return "emit_jump_insn";
   3149 
   3150     case UNKNOWN:
   3151       return NULL;
   3152 
   3153     default:
   3154       gcc_unreachable ();
   3155     }
   3156 }
   3157 
   3158 /* Return true if we must emit a barrier after pattern X.  */
   3159 
   3160 bool
   3161 needs_barrier_p (rtx x)
   3162 {
   3163   return (GET_CODE (x) == SET
   3164 	  && GET_CODE (SET_DEST (x)) == PC
   3165 	  && GET_CODE (SET_SRC (x)) == LABEL_REF);
   3166 }
   3167 
   3168 #define NS "NULL"
   3169 #define ZS "'\\0'"
   3170 #define OPTAB_CL(o, p, c, b, l)    { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
   3171 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
   3172 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
   3173 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
   3174 #define OPTAB_NC(o, p, c)          { #o, p, NS, ZS, NS, o, c, c, 3 },
   3175 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
   3176 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
   3177 #define OPTAB_VC(o, p, c)          { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
   3178 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
   3179 #define OPTAB_DC(o, p, c)          { #o, p, NS, ZS, NS, o, c, c, 4 },
   3180 #define OPTAB_D(o, p)  { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
   3181 
   3182 /* An array of all optabs.  Note that the same optab can appear more
   3183    than once, with a different pattern.  */
   3184 optab_def optabs[] = {
   3185   { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
   3186 #include "optabs.def"
   3187 };
   3188 
   3189 /* The number of entries in optabs[].  */
   3190 unsigned int num_optabs = ARRAY_SIZE (optabs);
   3191 
   3192 #undef OPTAB_CL
   3193 #undef OPTAB_CX
   3194 #undef OPTAB_CD
   3195 #undef OPTAB_NL
   3196 #undef OPTAB_NC
   3197 #undef OPTAB_NX
   3198 #undef OPTAB_VL
   3199 #undef OPTAB_VC
   3200 #undef OPTAB_VX
   3201 #undef OPTAB_DC
   3202 #undef OPTAB_D
   3203 
   3204 /* Return true if instruction NAME matches pattern PAT, storing information
   3205    about the match in P if so.  */
   3206 
   3207 static bool
   3208 match_pattern (optab_pattern *p, const char *name, const char *pat)
   3209 {
   3210   bool force_float = false;
   3211   bool force_int = false;
   3212   bool force_partial_int = false;
   3213   bool force_fixed = false;
   3214 
   3215   if (pat == NULL)
   3216     return false;
   3217   for (; ; ++pat)
   3218     {
   3219       if (*pat != '$')
   3220 	{
   3221 	  if (*pat != *name++)
   3222 	    return false;
   3223 	  if (*pat == '\0')
   3224 	    return true;
   3225 	  continue;
   3226 	}
   3227       switch (*++pat)
   3228 	{
   3229 	case 'I':
   3230 	  force_int = 1;
   3231 	  break;
   3232 	case 'P':
   3233 	  force_partial_int = 1;
   3234 	  break;
   3235 	case 'F':
   3236 	  force_float = 1;
   3237 	  break;
   3238 	case 'Q':
   3239 	  force_fixed = 1;
   3240 	  break;
   3241 
   3242 	case 'a':
   3243 	case 'b':
   3244 	  {
   3245 	    int i;
   3246 
   3247 	    /* This loop will stop at the first prefix match, so
   3248 	       look through the modes in reverse order, in case
   3249 	       there are extra CC modes and CC is a prefix of the
   3250 	       CC modes (as it should be).  */
   3251 	    for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
   3252 	      {
   3253 		const char *p, *q;
   3254 		for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
   3255 		  if (TOLOWER (*p) != *q)
   3256 		    break;
   3257 		if (*p == 0
   3258 		    && (! force_int || mode_class[i] == MODE_INT
   3259 			|| mode_class[i] == MODE_VECTOR_INT)
   3260 		    && (! force_partial_int
   3261 			|| mode_class[i] == MODE_INT
   3262 			|| mode_class[i] == MODE_PARTIAL_INT
   3263 			|| mode_class[i] == MODE_VECTOR_INT)
   3264 		    && (! force_float
   3265 			|| mode_class[i] == MODE_FLOAT
   3266 			|| mode_class[i] == MODE_DECIMAL_FLOAT
   3267 			|| mode_class[i] == MODE_COMPLEX_FLOAT
   3268 			|| mode_class[i] == MODE_VECTOR_FLOAT)
   3269 		    && (! force_fixed
   3270 			|| mode_class[i] == MODE_FRACT
   3271 			|| mode_class[i] == MODE_UFRACT
   3272 			|| mode_class[i] == MODE_ACCUM
   3273 			|| mode_class[i] == MODE_UACCUM
   3274 			|| mode_class[i] == MODE_VECTOR_FRACT
   3275 			|| mode_class[i] == MODE_VECTOR_UFRACT
   3276 			|| mode_class[i] == MODE_VECTOR_ACCUM
   3277 			|| mode_class[i] == MODE_VECTOR_UACCUM))
   3278 		  break;
   3279 	      }
   3280 
   3281 	    if (i < 0)
   3282 	      return false;
   3283 	    name += strlen (GET_MODE_NAME (i));
   3284 	    if (*pat == 'a')
   3285 	      p->m1 = i;
   3286 	    else
   3287 	      p->m2 = i;
   3288 
   3289 	    force_int = false;
   3290 	    force_partial_int = false;
   3291 	    force_float = false;
   3292 	    force_fixed = false;
   3293 	  }
   3294 	  break;
   3295 
   3296 	default:
   3297 	  gcc_unreachable ();
   3298 	}
   3299     }
   3300 }
   3301 
   3302 /* Return true if NAME is the name of an optab, describing it in P if so.  */
   3303 
   3304 bool
   3305 find_optab (optab_pattern *p, const char *name)
   3306 {
   3307   if (*name == 0 || *name == '*')
   3308     return false;
   3309 
   3310   /* See if NAME matches one of the patterns we have for the optabs
   3311      we know about.  */
   3312   for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
   3313     {
   3314       p->m1 = p->m2 = 0;
   3315       if (match_pattern (p, name, optabs[pindex].pattern))
   3316 	{
   3317 	  p->name = name;
   3318 	  p->op = optabs[pindex].op;
   3319 	  p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
   3320 	  return true;
   3321 	}
   3322     }
   3323   return false;
   3324 }
   3325