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