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