2016-09-26 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / gensupport.c
blob1648c9cc6493680b8dc95739bb6fdb099aecf7e0
1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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"
31 #define MAX_OPERANDS 40
33 static rtx operand_data[MAX_OPERANDS];
34 static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
35 static char used_operands_numbers[MAX_OPERANDS];
38 /* In case some macros used by files we include need it, define this here. */
39 int target_flags;
41 int insn_elision = 1;
43 static struct obstack obstack;
44 struct obstack *rtl_obstack = &obstack;
46 /* Counter for named patterns and INSN_CODEs. */
47 static int insn_sequence_num;
49 /* Counter for define_splits. */
50 static int split_sequence_num;
52 /* Counter for define_peephole2s. */
53 static int peephole2_sequence_num;
55 static int predicable_default;
56 static const char *predicable_true;
57 static const char *predicable_false;
59 static const char *subst_true = "yes";
60 static const char *subst_false = "no";
62 static htab_t condition_table;
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. */
68 struct queue_elem
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;
78 #define MNEMONIC_ATTR_NAME "mnemonic"
79 #define MNEMONIC_HTAB_SIZE 1024
81 static struct queue_elem *define_attr_queue;
82 static struct queue_elem **define_attr_tail = &define_attr_queue;
83 static struct queue_elem *define_pred_queue;
84 static struct queue_elem **define_pred_tail = &define_pred_queue;
85 static struct queue_elem *define_insn_queue;
86 static struct queue_elem **define_insn_tail = &define_insn_queue;
87 static struct queue_elem *define_cond_exec_queue;
88 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
89 static struct queue_elem *define_subst_queue;
90 static struct queue_elem **define_subst_tail = &define_subst_queue;
91 static struct queue_elem *other_queue;
92 static struct queue_elem **other_tail = &other_queue;
93 static struct queue_elem *define_subst_attr_queue;
94 static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
96 /* Mapping from DEFINE_* rtxes to their location in the source file. */
97 static hash_map <rtx, file_location> *rtx_locs;
99 static void remove_constraints (rtx);
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 const char *alter_test_for_insn (struct queue_elem *,
106 struct queue_elem *);
107 static char *shift_output_template (char *, const char *, int);
108 static const char *alter_output_for_insn (struct queue_elem *,
109 struct queue_elem *,
110 int, int);
111 static void process_one_cond_exec (struct queue_elem *);
112 static void process_define_cond_exec (void);
113 static void init_predicate_table (void);
114 static void record_insn_name (int, const char *);
116 static bool has_subst_attribute (struct queue_elem *, struct queue_elem *);
117 static const char * alter_output_for_subst_insn (rtx, int);
118 static void alter_attrs_for_subst_insn (struct queue_elem *, int);
119 static void process_substs_on_one_elem (struct queue_elem *,
120 struct queue_elem *);
121 static rtx subst_dup (rtx, int, int);
122 static void process_define_subst (void);
124 static const char * duplicate_alternatives (const char *, int);
125 static const char * duplicate_each_alternative (const char * str, int n_dup);
127 typedef const char * (*constraints_handler_t) (const char *, int);
128 static rtx alter_constraints (rtx, int, constraints_handler_t);
129 static rtx adjust_operands_numbers (rtx);
130 static rtx replace_duplicating_operands_in_pattern (rtx);
132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
133 the gensupport programs. */
136 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
137 HOST_WIDE_INT arg)
139 rtx rt = rtx_alloc (CONST_INT);
141 XWINT (rt, 0) = arg;
142 return rt;
145 /* Return the rtx pattern specified by the list of rtxes in a
146 define_insn or define_split. */
149 add_implicit_parallel (rtvec vec)
151 if (GET_NUM_ELEM (vec) == 1)
152 return RTVEC_ELT (vec, 0);
153 else
155 rtx pattern = rtx_alloc (PARALLEL);
156 XVEC (pattern, 0) = vec;
157 return pattern;
161 /* Predicate handling.
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.
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.
175 validate_pattern will warn about predicates that allow non-lvalues
176 when they appear in destination operands.
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.
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
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. */
197 #define N 0
198 #define Y 1
199 #define I 2
201 #define TRISTATE_AND(a,b) \
202 ((a) == I ? ((b) == N ? N : I) : \
203 (b) == I ? ((a) == N ? N : I) : \
204 (a) && (b))
206 #define TRISTATE_OR(a,b) \
207 ((a) == I ? ((b) == Y ? Y : I) : \
208 (b) == I ? ((a) == Y ? Y : I) : \
209 (a) || (b))
211 #define TRISTATE_NOT(a) \
212 ((a) == I ? I : !(a))
214 /* 0 means no warning about that code yet, 1 means warned. */
215 static char did_you_mean_codes[NUM_RTX_CODE];
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. */
221 void
222 compute_test_codes (rtx exp, file_location loc, char *codes)
224 char op0_codes[NUM_RTX_CODE];
225 char op1_codes[NUM_RTX_CODE];
226 char op2_codes[NUM_RTX_CODE];
227 int i;
229 switch (GET_CODE (exp))
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;
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;
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;
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')
267 memset (codes, Y, NUM_RTX_CODE);
268 break;
271 memset (codes, N, NUM_RTX_CODE);
273 const char *next_code = XSTR (exp, 0);
274 const char *code;
276 if (*next_code == '\0')
278 error_at (loc, "empty match_code expression");
279 break;
282 while ((code = scan_comma_elt (&next_code)) != 0)
284 size_t n = next_code - code;
285 int found_it = 0;
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')
291 codes[i] = Y;
292 found_it = 1;
293 break;
295 if (!found_it)
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])
304 did_you_mean_codes[i] = 1;
305 message_at (loc, "(did you mean \"%s\"?)",
306 GET_RTX_NAME (i));
311 break;
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. */
317 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
318 if (!p)
320 error_at (loc, "reference to unknown predicate '%s'",
321 XSTR (exp, 1));
322 break;
324 for (i = 0; i < NUM_RTX_CODE; i++)
325 codes[i] = p->codes[i] ? I : N;
327 break;
330 case MATCH_TEST:
331 /* (match_test WHATEVER) is completely indeterminate. */
332 memset (codes, I, NUM_RTX_CODE);
333 break;
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;
343 #undef TRISTATE_OR
344 #undef TRISTATE_AND
345 #undef TRISTATE_NOT
347 /* Return true if NAME is a valid predicate name. */
349 static bool
350 valid_predicate_name_p (const char *name)
352 const char *p;
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;
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. */
366 static void
367 process_define_predicate (rtx desc, file_location loc)
369 struct pred_data *pred;
370 char codes[NUM_RTX_CODE];
371 int i;
373 if (!valid_predicate_name_p (XSTR (desc, 0)))
375 error_at (loc, "%s: predicate name must be a valid C function name",
376 XSTR (desc, 0));
377 return;
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;
387 compute_test_codes (XEXP (desc, 1), loc, codes);
389 for (i = 0; i < NUM_RTX_CODE; i++)
390 if (codes[i] != N)
391 add_predicate_code (pred, (enum rtx_code) i);
393 add_predicate (pred);
395 #undef I
396 #undef N
397 #undef Y
399 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
400 element. */
402 static struct queue_elem *
403 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
404 file_location loc)
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;
416 /* Remove element ELEM from QUEUE. */
417 static void
418 remove_from_queue (struct queue_elem *elem, struct queue_elem **queue)
420 struct queue_elem *prev, *e;
421 prev = NULL;
422 for (e = *queue; e ; e = e->next)
424 if (e == elem)
425 break;
426 prev = e;
428 if (e == NULL)
429 return;
431 if (prev)
432 prev->next = elem->next;
433 else
434 *queue = elem->next;
437 /* Build a define_attr for an binary attribute with name NAME and
438 possible values "yes" and "no", and queue it. */
439 static void
440 add_define_attr (const char *name)
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);
450 e->next = define_attr_queue;
451 define_attr_queue = e;
455 /* Recursively remove constraints from an rtx. */
457 static void
458 remove_constraints (rtx part)
460 int i, j;
461 const char *format_ptr;
463 if (part == 0)
464 return;
466 if (GET_CODE (part) == MATCH_OPERAND)
467 XSTR (part, 2) = "";
468 else if (GET_CODE (part) == MATCH_SCRATCH)
469 XSTR (part, 1) = "";
471 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
473 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
474 switch (*format_ptr++)
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;
488 /* Process a top level rtx in some way, queuing as appropriate. */
490 static void
491 process_rtx (rtx desc, file_location loc)
493 switch (GET_CODE (desc))
495 case DEFINE_INSN:
496 queue_pattern (desc, &define_insn_tail, loc);
497 break;
499 case DEFINE_COND_EXEC:
500 queue_pattern (desc, &define_cond_exec_tail, loc);
501 break;
503 case DEFINE_SUBST:
504 queue_pattern (desc, &define_subst_tail, loc);
505 break;
507 case DEFINE_SUBST_ATTR:
508 queue_pattern (desc, &define_subst_attr_tail, loc);
509 break;
511 case DEFINE_ATTR:
512 case DEFINE_ENUM_ATTR:
513 queue_pattern (desc, &define_attr_tail, loc);
514 break;
516 case DEFINE_PREDICATE:
517 case DEFINE_SPECIAL_PREDICATE:
518 process_define_predicate (desc, loc);
519 /* Fall through. */
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;
529 case DEFINE_INSN_AND_SPLIT:
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;
538 /* Create a split with values from the insn_and_split. */
539 split = rtx_alloc (DEFINE_SPLIT);
541 i = XVECLEN (desc, 1);
542 XVEC (split, 0) = rtvec_alloc (i);
543 while (--i >= 0)
545 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
546 remove_constraints (XVECEXP (split, 0, i));
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] == '&')
554 copy_md_ptr_loc (split_cond + 2, split_cond);
555 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
557 XSTR (split, 1) = split_cond;
558 XVEC (split, 2) = XVEC (desc, 5);
559 XSTR (split, 3) = XSTR (desc, 6);
561 /* Fix up the DEFINE_INSN. */
562 attr = XVEC (desc, 7);
563 PUT_CODE (desc, DEFINE_INSN);
564 XVEC (desc, 4) = attr;
566 /* Queue them. */
567 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
568 split_elem = queue_pattern (split, &other_tail, loc);
569 insn_elem->split = split_elem;
570 break;
573 default:
574 queue_pattern (desc, &other_tail, loc);
575 break;
579 /* Return true if attribute PREDICABLE is true for ELEM, which holds
580 a DEFINE_INSN. */
582 static int
583 is_predicable (struct queue_elem *elem)
585 rtvec vec = XVEC (elem->data, 4);
586 const char *value;
587 int i;
589 if (! vec)
590 return predicable_default;
592 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
594 rtx sub = RTVEC_ELT (vec, i);
595 switch (GET_CODE (sub))
597 case SET_ATTR:
598 if (strcmp (XSTR (sub, 0), "predicable") == 0)
600 value = XSTR (sub, 1);
601 goto found;
603 break;
605 case SET_ATTR_ALTERNATIVE:
606 if (strcmp (XSTR (sub, 0), "predicable") == 0)
608 error_at (elem->loc, "multiple alternatives for `predicable'");
609 return 0;
611 break;
613 case SET:
614 if (GET_CODE (SET_DEST (sub)) != ATTR
615 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
616 break;
617 sub = SET_SRC (sub);
618 if (GET_CODE (sub) == CONST_STRING)
620 value = XSTR (sub, 0);
621 goto found;
624 /* ??? It would be possible to handle this if we really tried.
625 It's not easy though, and I'm not going to bother until it
626 really proves necessary. */
627 error_at (elem->loc, "non-constant value for `predicable'");
628 return 0;
630 default:
631 gcc_unreachable ();
635 return predicable_default;
637 found:
638 /* Find out which value we're looking at. Multiple alternatives means at
639 least one is predicable. */
640 if (strchr (value, ',') != NULL)
641 return 1;
642 if (strcmp (value, predicable_true) == 0)
643 return 1;
644 if (strcmp (value, predicable_false) == 0)
645 return 0;
647 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
648 return 0;
651 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
652 static void
653 change_subst_attribute (struct queue_elem *elem,
654 struct queue_elem *subst_elem,
655 const char *new_value)
657 rtvec attrs_vec = XVEC (elem->data, 4);
658 const char *subst_name = XSTR (subst_elem->data, 0);
659 int i;
661 if (! attrs_vec)
662 return;
664 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
666 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
667 if (GET_CODE (cur_attr) != SET_ATTR)
668 continue;
669 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
671 XSTR (cur_attr, 1) = new_value;
672 return;
677 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
678 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
679 DEFINE_SUBST isn't applied to patterns without such attribute. In other
680 words, we suppose the default value of the attribute to be 'no' since it is
681 always generated automaticaly in read-rtl.c. */
682 static bool
683 has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem)
685 rtvec attrs_vec = XVEC (elem->data, 4);
686 const char *value, *subst_name = XSTR (subst_elem->data, 0);
687 int i;
689 if (! attrs_vec)
690 return false;
692 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
694 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
695 switch (GET_CODE (cur_attr))
697 case SET_ATTR:
698 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
700 value = XSTR (cur_attr, 1);
701 goto found;
703 break;
705 case SET:
706 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
707 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
708 break;
709 cur_attr = SET_SRC (cur_attr);
710 if (GET_CODE (cur_attr) == CONST_STRING)
712 value = XSTR (cur_attr, 0);
713 goto found;
716 /* Only (set_attr "subst" "yes/no") and
717 (set (attr "subst" (const_string "yes/no")))
718 are currently allowed. */
719 error_at (elem->loc, "unsupported value for `%s'", subst_name);
720 return false;
722 case SET_ATTR_ALTERNATIVE:
723 error_at (elem->loc,
724 "%s: `set_attr_alternative' is unsupported by "
725 "`define_subst'", XSTR (elem->data, 0));
726 return false;
729 default:
730 gcc_unreachable ();
734 return false;
736 found:
737 if (strcmp (value, subst_true) == 0)
738 return true;
739 if (strcmp (value, subst_false) == 0)
740 return false;
742 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
743 value, subst_name);
744 return false;
747 /* Compare RTL-template of original define_insn X to input RTL-template of
748 define_subst PT. Return 1 if the templates match, 0 otherwise.
749 During the comparison, the routine also fills global_array OPERAND_DATA. */
750 static bool
751 subst_pattern_match (rtx x, rtx pt, file_location loc)
753 RTX_CODE code, code_pt;
754 int i, j, len;
755 const char *fmt, *pred_name;
757 code = GET_CODE (x);
758 code_pt = GET_CODE (pt);
760 if (code_pt == MATCH_OPERAND)
762 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
763 always accept them. */
764 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
765 && (code != MATCH_DUP && code != MATCH_OP_DUP))
766 return false; /* Modes don't match. */
768 if (code == MATCH_OPERAND)
770 pred_name = XSTR (pt, 1);
771 if (pred_name[0] != 0)
773 const struct pred_data *pred_pt = lookup_predicate (pred_name);
774 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
775 return false; /* Predicates don't match. */
779 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
780 operand_data[XINT (pt, 0)] = x;
781 return true;
784 if (code_pt == MATCH_OPERATOR)
786 int x_vecexp_pos = -1;
788 /* Compare modes. */
789 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
790 return false;
792 /* In case X is also match_operator, compare predicates. */
793 if (code == MATCH_OPERATOR)
795 pred_name = XSTR (pt, 1);
796 if (pred_name[0] != 0)
798 const struct pred_data *pred_pt = lookup_predicate (pred_name);
799 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
800 return false;
804 /* Compare operands.
805 MATCH_OPERATOR in input template could match in original template
806 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
807 In the first case operands are at (XVECEXP (x, 2, j)), in the second
808 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
809 X_VECEXP_POS variable shows, where to look for these operands. */
810 if (code == UNSPEC
811 || code == UNSPEC_VOLATILE)
812 x_vecexp_pos = 0;
813 else if (code == MATCH_OPERATOR)
814 x_vecexp_pos = 2;
815 else
816 x_vecexp_pos = -1;
818 /* MATCH_OPERATOR or UNSPEC case. */
819 if (x_vecexp_pos >= 0)
821 /* Compare operands number in X and PT. */
822 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
823 return false;
824 for (j = 0; j < XVECLEN (pt, 2); j++)
825 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
826 XVECEXP (pt, 2, j), loc))
827 return false;
830 /* Ordinary operator. */
831 else
833 /* Compare operands number in X and PT.
834 We count operands differently for X and PT since we compare
835 an operator (with operands directly in RTX) and MATCH_OPERATOR
836 (that has a vector with operands). */
837 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
838 return false;
839 for (j = 0; j < XVECLEN (pt, 2); j++)
840 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
841 return false;
844 /* Store the operand to OPERAND_DATA array. */
845 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
846 operand_data[XINT (pt, 0)] = x;
847 return true;
850 if (code_pt == MATCH_PAR_DUP
851 || code_pt == MATCH_DUP
852 || code_pt == MATCH_OP_DUP
853 || code_pt == MATCH_SCRATCH
854 || code_pt == MATCH_PARALLEL)
856 /* Currently interface for these constructions isn't defined -
857 probably they aren't needed in input template of define_subst at all.
858 So, for now their usage in define_subst is forbidden. */
859 error_at (loc, "%s cannot be used in define_subst",
860 GET_RTX_NAME (code_pt));
863 gcc_assert (code != MATCH_PAR_DUP
864 && code_pt != MATCH_DUP
865 && code_pt != MATCH_OP_DUP
866 && code_pt != MATCH_SCRATCH
867 && code_pt != MATCH_PARALLEL
868 && code_pt != MATCH_OPERAND
869 && code_pt != MATCH_OPERATOR);
870 /* If PT is none of the handled above, then we match only expressions with
871 the same code in X. */
872 if (code != code_pt)
873 return false;
875 fmt = GET_RTX_FORMAT (code_pt);
876 len = GET_RTX_LENGTH (code_pt);
878 for (i = 0; i < len; i++)
880 if (fmt[i] == '0')
881 break;
883 switch (fmt[i])
885 case 'i': case 'r': case 'w': case 's':
886 continue;
888 case 'e': case 'u':
889 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
890 return false;
891 break;
892 case 'E':
894 if (XVECLEN (x, i) != XVECLEN (pt, i))
895 return false;
896 for (j = 0; j < XVECLEN (pt, i); j++)
897 if (!subst_pattern_match (XVECEXP (x, i, j),
898 XVECEXP (pt, i, j), loc))
899 return false;
900 break;
902 default:
903 gcc_unreachable ();
907 return true;
910 /* Examine the attribute "predicable"; discover its boolean values
911 and its default. */
913 static void
914 identify_predicable_attribute (void)
916 struct queue_elem *elem;
917 char *p_true, *p_false;
918 const char *value;
920 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
921 for (elem = define_attr_queue; elem ; elem = elem->next)
922 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
923 goto found;
925 error_at (define_cond_exec_queue->loc,
926 "attribute `predicable' not defined");
927 return;
929 found:
930 value = XSTR (elem->data, 1);
931 p_false = xstrdup (value);
932 p_true = strchr (p_false, ',');
933 if (p_true == NULL || strchr (++p_true, ',') != NULL)
935 error_at (elem->loc, "attribute `predicable' is not a boolean");
936 free (p_false);
937 return;
939 p_true[-1] = '\0';
941 predicable_true = p_true;
942 predicable_false = p_false;
944 switch (GET_CODE (XEXP (elem->data, 2)))
946 case CONST_STRING:
947 value = XSTR (XEXP (elem->data, 2), 0);
948 break;
950 case CONST:
951 error_at (elem->loc, "attribute `predicable' cannot be const");
952 free (p_false);
953 return;
955 default:
956 error_at (elem->loc,
957 "attribute `predicable' must have a constant default");
958 free (p_false);
959 return;
962 if (strcmp (value, p_true) == 0)
963 predicable_default = 1;
964 else if (strcmp (value, p_false) == 0)
965 predicable_default = 0;
966 else
968 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
969 value);
970 free (p_false);
974 /* Return the number of alternatives in constraint S. */
976 static int
977 n_alternatives (const char *s)
979 int n = 1;
981 if (s)
982 while (*s)
983 n += (*s++ == ',');
985 return n;
988 /* The routine scans rtl PATTERN, find match_operand in it and counts
989 number of alternatives. If PATTERN contains several match_operands
990 with different number of alternatives, error is emitted, and the
991 routine returns 0. If all match_operands in PATTERN have the same
992 number of alternatives, it's stored in N_ALT, and the routine returns 1.
993 LOC is the location of PATTERN, for error reporting. */
994 static int
995 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
997 const char *fmt;
998 enum rtx_code code;
999 int i, j, len;
1001 if (!n_alt)
1002 return 0;
1004 code = GET_CODE (pattern);
1005 switch (code)
1007 case MATCH_OPERAND:
1008 i = n_alternatives (XSTR (pattern, 2));
1009 /* n_alternatives returns 1 if constraint string is empty -
1010 here we fix it up. */
1011 if (!*(XSTR (pattern, 2)))
1012 i = 0;
1013 if (*n_alt <= 0)
1014 *n_alt = i;
1016 else if (i && i != *n_alt)
1018 error_at (loc, "wrong number of alternatives in operand %d",
1019 XINT (pattern, 0));
1020 return 0;
1023 default:
1024 break;
1027 fmt = GET_RTX_FORMAT (code);
1028 len = GET_RTX_LENGTH (code);
1029 for (i = 0; i < len; i++)
1031 switch (fmt[i])
1033 case 'e': case 'u':
1034 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1035 return 0;
1036 break;
1038 case 'V':
1039 if (XVEC (pattern, i) == NULL)
1040 break;
1041 /* FALLTHRU */
1043 case 'E':
1044 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1045 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1046 return 0;
1047 break;
1049 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1050 break;
1052 default:
1053 gcc_unreachable ();
1056 return 1;
1059 /* Determine how many alternatives there are in INSN, and how many
1060 operands. */
1062 static void
1063 collect_insn_data (rtx pattern, int *palt, int *pmax)
1065 const char *fmt;
1066 enum rtx_code code;
1067 int i, j, len;
1069 code = GET_CODE (pattern);
1070 switch (code)
1072 case MATCH_OPERAND:
1073 case MATCH_SCRATCH:
1074 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1075 *palt = (i > *palt ? i : *palt);
1076 /* Fall through. */
1078 case MATCH_OPERATOR:
1079 case MATCH_PARALLEL:
1080 i = XINT (pattern, 0);
1081 if (i > *pmax)
1082 *pmax = i;
1083 break;
1085 default:
1086 break;
1089 fmt = GET_RTX_FORMAT (code);
1090 len = GET_RTX_LENGTH (code);
1091 for (i = 0; i < len; i++)
1093 switch (fmt[i])
1095 case 'e': case 'u':
1096 collect_insn_data (XEXP (pattern, i), palt, pmax);
1097 break;
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;
1108 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1109 break;
1111 default:
1112 gcc_unreachable ();
1117 static rtx
1118 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1119 file_location loc)
1121 const char *fmt;
1122 enum rtx_code code;
1123 int i, j, len;
1125 code = GET_CODE (pattern);
1126 switch (code)
1128 case MATCH_OPERAND:
1130 const char *c = XSTR (pattern, 2);
1132 if (n_alternatives (c) != 1)
1134 error_at (loc, "too many alternatives for operand %d",
1135 XINT (pattern, 0));
1136 return NULL;
1139 /* Replicate C as needed to fill out ALT alternatives. */
1140 if (c && *c && alt > 1)
1142 size_t c_len = strlen (c);
1143 size_t len = alt * (c_len + 1);
1144 char *new_c = XNEWVEC (char, len);
1146 memcpy (new_c, c, c_len);
1147 for (i = 1; i < alt; ++i)
1149 new_c[i * (c_len + 1) - 1] = ',';
1150 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1152 new_c[len - 1] = '\0';
1153 XSTR (pattern, 2) = new_c;
1156 /* Fall through. */
1158 case MATCH_OPERATOR:
1159 case MATCH_SCRATCH:
1160 case MATCH_PARALLEL:
1161 XINT (pattern, 0) += max_op;
1162 break;
1164 default:
1165 break;
1168 fmt = GET_RTX_FORMAT (code);
1169 len = GET_RTX_LENGTH (code);
1170 for (i = 0; i < len; i++)
1172 rtx r;
1174 switch (fmt[i])
1176 case 'e': case 'u':
1177 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1178 if (r == NULL)
1179 return r;
1180 break;
1182 case 'E':
1183 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1185 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1186 alt, max_op, loc);
1187 if (r == NULL)
1188 return r;
1190 break;
1192 case 'i': case 'r': case 'w': case '0': case 's':
1193 break;
1195 default:
1196 gcc_unreachable ();
1200 return pattern;
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)
1212 const char *fmt;
1213 enum rtx_code code;
1214 int i, j, len;
1216 code = GET_CODE (pattern);
1217 switch (code)
1219 case MATCH_OPERAND:
1220 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1221 break;
1223 default:
1224 break;
1227 fmt = GET_RTX_FORMAT (code);
1228 len = GET_RTX_LENGTH (code);
1229 for (i = 0; i < len; i++)
1231 rtx r;
1233 switch (fmt[i])
1235 case 'e': case 'u':
1236 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1237 if (r == NULL)
1238 return r;
1239 break;
1241 case 'E':
1242 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1244 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1245 if (r == NULL)
1246 return r;
1248 break;
1250 case 'i': case 'r': case 'w': case '0': case 's':
1251 break;
1253 default:
1254 break;
1258 return pattern;
1261 static const char *
1262 alter_test_for_insn (struct queue_elem *ce_elem,
1263 struct queue_elem *insn_elem)
1265 return join_c_conditions (XSTR (ce_elem->data, 1),
1266 XSTR (insn_elem->data, 2));
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)
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);
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;
1287 return ite;
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. */
1297 static void
1298 alter_attrs_for_insn (rtx insn)
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;
1309 if (! vec)
1310 return;
1312 num_elem = GET_NUM_ELEM (vec);
1313 for (i = num_elem - 1; i >= 0; --i)
1315 rtx sub = RTVEC_ELT (vec, i);
1316 switch (GET_CODE (sub))
1318 case SET_ATTR:
1319 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1321 predicable_idx = i;
1322 XSTR (sub, 0) = "ce_enabled";
1324 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1326 enabled_idx = i;
1327 XSTR (sub, 0) = "nonce_enabled";
1329 break;
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)
1337 enabled_idx = i;
1338 XSTR (sub, 0) = "nonce_enabled";
1340 break;
1342 case SET:
1343 if (GET_CODE (SET_DEST (sub)) != ATTR)
1344 break;
1345 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1347 sub = SET_SRC (sub);
1348 if (GET_CODE (sub) == CONST_STRING)
1350 predicable_idx = i;
1351 XSTR (sub, 0) = "ce_enabled";
1353 else
1354 /* We already give an error elsewhere. */
1355 return;
1356 break;
1358 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1360 enabled_idx = i;
1361 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1363 break;
1365 default:
1366 gcc_unreachable ();
1369 if (predicable_idx == -1)
1370 return;
1372 if (!global_changes_made)
1374 struct queue_elem *elem;
1376 global_changes_made = true;
1377 add_define_attr ("ce_enabled");
1378 add_define_attr ("nonce_enabled");
1380 for (elem = define_attr_queue; elem ; elem = elem->next)
1381 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1383 XEXP (elem->data, 2)
1384 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1387 if (enabled_idx == -1)
1388 return;
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;
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)
1417 rtvec vec = XVEC (elem->data, 4);
1418 int num_elem;
1419 int i;
1421 if (n_dup < 2 || ! vec)
1422 return;
1424 num_elem = GET_NUM_ELEM (vec);
1425 for (i = num_elem - 1; i >= 0; --i)
1427 rtx sub = RTVEC_ELT (vec, i);
1428 switch (GET_CODE (sub))
1430 case SET_ATTR:
1431 if (strchr (XSTR (sub, 1), ',') != NULL)
1432 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1433 break;
1435 case SET_ATTR_ALTERNATIVE:
1436 case SET:
1437 error_at (elem->loc,
1438 "%s: `define_subst' does not support attributes "
1439 "assigned by `set' and `set_attr_alternative'",
1440 XSTR (elem->data, 0));
1441 return;
1443 default:
1444 gcc_unreachable ();
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. */
1453 static char *
1454 shift_output_template (char *dest, const char *src, int disp)
1456 while (*src)
1458 char c = *src++;
1459 *dest++ = c;
1460 if (c == '%')
1462 c = *src++;
1463 if (ISDIGIT ((unsigned char) c))
1464 c += disp;
1465 else if (ISALPHA (c))
1467 *dest++ = c;
1468 c = *src++ + disp;
1470 *dest++ = c;
1474 return dest;
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)
1482 const char *ce_out, *insn_out;
1483 char *result, *p;
1484 size_t len, ce_len, insn_len;
1486 /* ??? Could coordinate with genoutput to not duplicate code here. */
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;
1493 ce_len = strlen (ce_out);
1494 insn_len = strlen (insn_out);
1496 if (*insn_out == '*')
1497 /* You must take care of the predicate yourself. */
1498 return insn_out;
1500 if (*insn_out == '@')
1502 len = (ce_len + 1) * alt + insn_len + 1;
1503 p = result = XNEWVEC (char, len);
1508 *p++ = *insn_out++;
1509 while (ISSPACE ((unsigned char) *insn_out));
1511 if (*insn_out != '#')
1513 p = shift_output_template (p, ce_out, max_op);
1514 *p++ = ' ';
1518 *p++ = *insn_out++;
1519 while (*insn_out && *insn_out != '\n');
1521 while (*insn_out);
1522 *p = '\0';
1524 else
1526 len = ce_len + 1 + insn_len + 1;
1527 result = XNEWVEC (char, len);
1529 p = shift_output_template (result, ce_out, max_op);
1530 *p++ = ' ';
1531 memcpy (p, insn_out, insn_len + 1);
1534 return result;
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. */
1540 static const char *
1541 duplicate_alternatives (const char * str, int n_dup)
1543 int i, len, new_len;
1544 char *result, *sp;
1545 const char *cp;
1547 if (n_dup < 2)
1548 return str;
1550 while (ISSPACE (*str))
1551 str++;
1553 if (*str == '\0')
1554 return str;
1556 cp = str;
1557 len = strlen (str);
1558 new_len = (len + 1) * n_dup;
1560 sp = result = XNEWVEC (char, new_len);
1562 /* Global modifier characters mustn't be duplicated: skip if found. */
1563 if (*cp == '=' || *cp == '+' || *cp == '%')
1565 *sp++ = *cp++;
1566 len--;
1569 /* Copy original constraints N_DUP times. */
1570 for (i = 0; i < n_dup; i++, sp += len+1)
1572 memcpy (sp, cp, len);
1573 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1576 return result;
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)
1584 int i, len, new_len;
1585 char *result, *sp, *ep, *cp;
1587 if (n_dup < 2)
1588 return str;
1590 while (ISSPACE (*str))
1591 str++;
1593 if (*str == '\0')
1594 return str;
1596 cp = xstrdup (str);
1598 new_len = (strlen (cp) + 1) * n_dup;
1600 sp = result = XNEWVEC (char, new_len);
1602 /* Global modifier characters mustn't be duplicated: skip if found. */
1603 if (*cp == '=' || *cp == '+' || *cp == '%')
1604 *sp++ = *cp++;
1608 if ((ep = strchr (cp, ',')) != NULL)
1609 *ep++ = '\0';
1610 len = strlen (cp);
1612 /* Copy a constraint N_DUP times. */
1613 for (i = 0; i < n_dup; i++, sp += len + 1)
1615 memcpy (sp, cp, len);
1616 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1619 cp = ep;
1621 while (cp != NULL);
1623 return result;
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. */
1632 static const char *
1633 alter_output_for_subst_insn (rtx insn, int alt)
1635 const char *insn_out, *old_out;
1636 char *new_out, *cp;
1637 size_t old_len, new_len;
1638 int j;
1640 insn_out = XTMPL (insn, 3);
1642 if (alt < 2 || *insn_out != '@')
1643 return insn_out;
1645 old_out = insn_out + 1;
1646 while (ISSPACE (*old_out))
1647 old_out++;
1648 old_len = strlen (old_out);
1650 new_len = alt * (old_len + 1) + 1;
1652 new_out = XNEWVEC (char, new_len);
1653 new_out[0] = '@';
1655 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
1657 memcpy (cp, old_out, old_len);
1658 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
1661 return new_out;
1664 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1666 static void
1667 process_one_cond_exec (struct queue_elem *ce_elem)
1669 struct queue_elem *insn_elem;
1670 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1672 int alternatives, max_operand;
1673 rtx pred, insn, pattern, split;
1674 char *new_name;
1675 int i;
1677 if (! is_predicable (insn_elem))
1678 continue;
1680 alternatives = 1;
1681 max_operand = -1;
1682 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1683 max_operand += 1;
1685 if (XVECLEN (ce_elem->data, 0) != 1)
1687 error_at (ce_elem->loc, "too many patterns in predicate");
1688 return;
1691 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1692 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1693 ce_elem->loc);
1694 if (pred == NULL)
1695 return;
1697 /* Construct a new pattern for the new insn. */
1698 insn = copy_rtx (insn_elem->data);
1699 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1700 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1701 XSTR (insn, 0) = new_name;
1702 pattern = rtx_alloc (COND_EXEC);
1703 XEXP (pattern, 0) = pred;
1704 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
1705 XVEC (insn, 1) = rtvec_alloc (1);
1706 XVECEXP (insn, 1, 0) = pattern;
1708 if (XVEC (ce_elem->data, 3) != NULL)
1710 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
1711 + XVECLEN (ce_elem->data, 3));
1712 int i = 0;
1713 int j = 0;
1714 for (i = 0; i < XVECLEN (insn, 4); i++)
1715 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
1717 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
1718 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
1720 XVEC (insn, 4) = attributes;
1723 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1724 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1725 alternatives, max_operand);
1726 alter_attrs_for_insn (insn);
1728 /* Put the new pattern on the `other' list so that it
1729 (a) is not reprocessed by other define_cond_exec patterns
1730 (b) appears after all normal define_insn patterns.
1732 ??? B is debatable. If one has normal insns that match
1733 cond_exec patterns, they will be preferred over these
1734 generated patterns. Whether this matters in practice, or if
1735 it's a good thing, or whether we should thread these new
1736 patterns into the define_insn chain just after their generator
1737 is something we'll have to experiment with. */
1739 queue_pattern (insn, &other_tail, insn_elem->loc);
1741 if (!insn_elem->split)
1742 continue;
1744 /* If the original insn came from a define_insn_and_split,
1745 generate a new split to handle the predicated insn. */
1746 split = copy_rtx (insn_elem->split->data);
1747 /* Predicate the pattern matched by the split. */
1748 pattern = rtx_alloc (COND_EXEC);
1749 XEXP (pattern, 0) = pred;
1750 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
1751 XVEC (split, 0) = rtvec_alloc (1);
1752 XVECEXP (split, 0, 0) = pattern;
1754 /* Predicate all of the insns generated by the split. */
1755 for (i = 0; i < XVECLEN (split, 2); i++)
1757 pattern = rtx_alloc (COND_EXEC);
1758 XEXP (pattern, 0) = pred;
1759 XEXP (pattern, 1) = XVECEXP (split, 2, i);
1760 XVECEXP (split, 2, i) = pattern;
1762 /* Add the new split to the queue. */
1763 queue_pattern (split, &other_tail, insn_elem->split->loc);
1767 /* Try to apply define_substs to the given ELEM.
1768 Only define_substs, specified via attributes would be applied.
1769 If attribute, requiring define_subst, is set, but no define_subst
1770 was applied, ELEM would be deleted. */
1772 static void
1773 process_substs_on_one_elem (struct queue_elem *elem,
1774 struct queue_elem *queue)
1776 struct queue_elem *subst_elem;
1777 int i, j, patterns_match;
1779 for (subst_elem = define_subst_queue;
1780 subst_elem; subst_elem = subst_elem->next)
1782 int alternatives, alternatives_subst;
1783 rtx subst_pattern;
1784 rtvec subst_pattern_vec;
1786 if (!has_subst_attribute (elem, subst_elem))
1787 continue;
1789 /* Compare original rtl-pattern from define_insn with input
1790 pattern from define_subst.
1791 Also, check if numbers of alternatives are the same in all
1792 match_operands. */
1793 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1794 continue;
1795 patterns_match = 1;
1796 alternatives = -1;
1797 alternatives_subst = -1;
1798 for (j = 0; j < XVECLEN (elem->data, 1); j++)
1800 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1801 XVECEXP (subst_elem->data, 1, j),
1802 subst_elem->loc))
1804 patterns_match = 0;
1805 break;
1808 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1809 &alternatives, subst_elem->loc))
1811 patterns_match = 0;
1812 break;
1816 /* Check if numbers of alternatives are the same in all
1817 match_operands in output template of define_subst. */
1818 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1820 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1821 &alternatives_subst,
1822 subst_elem->loc))
1824 patterns_match = 0;
1825 break;
1829 if (!patterns_match)
1830 continue;
1832 /* Clear array in which we save occupied indexes of operands. */
1833 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1835 /* Create a pattern, based on the output one from define_subst. */
1836 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1837 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1839 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1841 /* Duplicate constraints in substitute-pattern. */
1842 subst_pattern = alter_constraints (subst_pattern, alternatives,
1843 duplicate_each_alternative);
1845 subst_pattern = adjust_operands_numbers (subst_pattern);
1847 /* Substitute match_dup and match_op_dup in the new pattern and
1848 duplicate constraints. */
1849 subst_pattern = subst_dup (subst_pattern, alternatives,
1850 alternatives_subst);
1852 replace_duplicating_operands_in_pattern (subst_pattern);
1854 /* We don't need any constraints in DEFINE_EXPAND. */
1855 if (GET_CODE (elem->data) == DEFINE_EXPAND)
1856 remove_constraints (subst_pattern);
1858 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1860 XVEC (elem->data, 1) = subst_pattern_vec;
1862 for (i = 0; i < MAX_OPERANDS; i++)
1863 match_operand_entries_in_pattern[i] = NULL;
1865 if (GET_CODE (elem->data) == DEFINE_INSN)
1867 XTMPL (elem->data, 3) =
1868 alter_output_for_subst_insn (elem->data, alternatives_subst);
1869 alter_attrs_for_subst_insn (elem, alternatives_subst);
1872 /* Recalculate condition, joining conditions from original and
1873 DEFINE_SUBST input patterns. */
1874 XSTR (elem->data, 2) = join_c_conditions (XSTR (subst_elem->data, 2),
1875 XSTR (elem->data, 2));
1876 /* Mark that subst was applied by changing attribute from "yes"
1877 to "no". */
1878 change_subst_attribute (elem, subst_elem, subst_false);
1881 /* If ELEM contains a subst attribute with value "yes", then we
1882 expected that a subst would be applied, but it wasn't - so,
1883 we need to remove that elementto avoid duplicating. */
1884 for (subst_elem = define_subst_queue;
1885 subst_elem; subst_elem = subst_elem->next)
1887 if (has_subst_attribute (elem, subst_elem))
1889 remove_from_queue (elem, &queue);
1890 return;
1895 /* This is a subroutine of mark_operands_used_in_match_dup.
1896 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1897 static void
1898 mark_operands_from_match_dup (rtx pattern)
1900 const char *fmt;
1901 int i, j, len, opno;
1903 if (GET_CODE (pattern) == MATCH_OPERAND
1904 || GET_CODE (pattern) == MATCH_OPERATOR
1905 || GET_CODE (pattern) == MATCH_PARALLEL)
1907 opno = XINT (pattern, 0);
1908 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1909 used_operands_numbers [opno] = 1;
1911 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1912 len = GET_RTX_LENGTH (GET_CODE (pattern));
1913 for (i = 0; i < len; i++)
1915 switch (fmt[i])
1917 case 'e': case 'u':
1918 mark_operands_from_match_dup (XEXP (pattern, i));
1919 break;
1920 case 'E':
1921 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1922 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
1923 break;
1928 /* This is a subroutine of adjust_operands_numbers.
1929 It goes through all expressions in PATTERN and when MATCH_DUP is
1930 met, all MATCH_OPERANDs inside it is marked as occupied. The
1931 process of marking is done by routin mark_operands_from_match_dup. */
1932 static void
1933 mark_operands_used_in_match_dup (rtx pattern)
1935 const char *fmt;
1936 int i, j, len, opno;
1938 if (GET_CODE (pattern) == MATCH_DUP)
1940 opno = XINT (pattern, 0);
1941 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1942 mark_operands_from_match_dup (operand_data[opno]);
1943 return;
1945 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1946 len = GET_RTX_LENGTH (GET_CODE (pattern));
1947 for (i = 0; i < len; i++)
1949 switch (fmt[i])
1951 case 'e': case 'u':
1952 mark_operands_used_in_match_dup (XEXP (pattern, i));
1953 break;
1954 case 'E':
1955 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1956 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
1957 break;
1962 /* This is subroutine of renumerate_operands_in_pattern.
1963 It finds first not-occupied operand-index. */
1964 static int
1965 find_first_unused_number_of_operand ()
1967 int i;
1968 for (i = 0; i < MAX_OPERANDS; i++)
1969 if (!used_operands_numbers[i])
1970 return i;
1971 return MAX_OPERANDS;
1974 /* This is subroutine of adjust_operands_numbers.
1975 It visits all expressions in PATTERN and assigns not-occupied
1976 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1977 PATTERN. */
1978 static void
1979 renumerate_operands_in_pattern (rtx pattern)
1981 const char *fmt;
1982 enum rtx_code code;
1983 int i, j, len, new_opno;
1984 code = GET_CODE (pattern);
1986 if (code == MATCH_OPERAND
1987 || code == MATCH_OPERATOR)
1989 new_opno = find_first_unused_number_of_operand ();
1990 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
1991 XINT (pattern, 0) = new_opno;
1992 used_operands_numbers [new_opno] = 1;
1995 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1996 len = GET_RTX_LENGTH (GET_CODE (pattern));
1997 for (i = 0; i < len; i++)
1999 switch (fmt[i])
2001 case 'e': case 'u':
2002 renumerate_operands_in_pattern (XEXP (pattern, i));
2003 break;
2004 case 'E':
2005 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2006 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2007 break;
2012 /* If output pattern of define_subst contains MATCH_DUP, then this
2013 expression would be replaced with the pattern, matched with
2014 MATCH_OPERAND from input pattern. This pattern could contain any
2015 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2016 that a MATCH_OPERAND from output_pattern (if any) would have the
2017 same number, as MATCH_OPERAND from copied pattern. To avoid such
2018 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2019 laying in the output pattern outside of MATCH_DUPs. */
2020 static rtx
2021 adjust_operands_numbers (rtx pattern)
2023 mark_operands_used_in_match_dup (pattern);
2025 renumerate_operands_in_pattern (pattern);
2027 return pattern;
2030 /* Generate RTL expression
2031 (match_dup OPNO)
2033 static rtx
2034 generate_match_dup (int opno)
2036 rtx return_rtx = rtx_alloc (MATCH_DUP);
2037 PUT_CODE (return_rtx, MATCH_DUP);
2038 XINT (return_rtx, 0) = opno;
2039 return return_rtx;
2042 /* This routine checks all match_operands in PATTERN and if some of
2043 have the same index, it replaces all of them except the first one to
2044 match_dup.
2045 Usually, match_operands with the same indexes are forbidden, but
2046 after define_subst copy an RTL-expression from original template,
2047 indexes of existed and just-copied match_operands could coincide.
2048 To fix it, we replace one of them with match_dup. */
2049 static rtx
2050 replace_duplicating_operands_in_pattern (rtx pattern)
2052 const char *fmt;
2053 int i, j, len, opno;
2054 rtx mdup;
2056 if (GET_CODE (pattern) == MATCH_OPERAND)
2058 opno = XINT (pattern, 0);
2059 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2060 if (match_operand_entries_in_pattern[opno] == NULL)
2062 match_operand_entries_in_pattern[opno] = pattern;
2063 return NULL;
2065 else
2067 /* Compare predicates before replacing with match_dup. */
2068 if (strcmp (XSTR (pattern, 1),
2069 XSTR (match_operand_entries_in_pattern[opno], 1)))
2071 error ("duplicated match_operands with different predicates were"
2072 " found.");
2073 return NULL;
2075 return generate_match_dup (opno);
2078 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2079 len = GET_RTX_LENGTH (GET_CODE (pattern));
2080 for (i = 0; i < len; i++)
2082 switch (fmt[i])
2084 case 'e': case 'u':
2085 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2086 if (mdup)
2087 XEXP (pattern, i) = mdup;
2088 break;
2089 case 'E':
2090 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2092 mdup =
2093 replace_duplicating_operands_in_pattern (XVECEXP
2094 (pattern, i, j));
2095 if (mdup)
2096 XVECEXP (pattern, i, j) = mdup;
2098 break;
2101 return NULL;
2104 /* The routine modifies given input PATTERN of define_subst, replacing
2105 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2106 pattern, whose operands are stored in OPERAND_DATA array.
2107 It also duplicates constraints in operands - constraints from
2108 define_insn operands are duplicated N_SUBST_ALT times, constraints
2109 from define_subst operands are duplicated N_ALT times.
2110 After the duplication, returned output rtl-pattern contains every
2111 combination of input constraints Vs constraints from define_subst
2112 output. */
2113 static rtx
2114 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2116 const char *fmt;
2117 enum rtx_code code;
2118 int i, j, len, opno;
2120 code = GET_CODE (pattern);
2121 switch (code)
2123 case MATCH_DUP:
2124 case MATCH_OP_DUP:
2125 opno = XINT (pattern, 0);
2127 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2129 if (operand_data[opno])
2131 pattern = copy_rtx (operand_data[opno]);
2133 /* Duplicate constraints. */
2134 pattern = alter_constraints (pattern, n_subst_alt,
2135 duplicate_alternatives);
2137 break;
2139 default:
2140 break;
2143 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2144 len = GET_RTX_LENGTH (GET_CODE (pattern));
2145 for (i = 0; i < len; i++)
2147 switch (fmt[i])
2149 case 'e': case 'u':
2150 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2151 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2152 n_alt, n_subst_alt);
2153 break;
2154 case 'V':
2155 if (XVEC (pattern, i) == NULL)
2156 break;
2157 /* FALLTHRU */
2158 case 'E':
2159 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2160 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2161 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2162 n_alt, n_subst_alt);
2163 break;
2165 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2166 break;
2168 default:
2169 gcc_unreachable ();
2172 return pattern;
2175 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2176 patterns appropriately. */
2178 static void
2179 process_define_cond_exec (void)
2181 struct queue_elem *elem;
2183 identify_predicable_attribute ();
2184 if (have_error)
2185 return;
2187 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2188 process_one_cond_exec (elem);
2191 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2192 DEFINE_EXPAND patterns appropriately. */
2194 static void
2195 process_define_subst (void)
2197 struct queue_elem *elem, *elem_attr;
2199 /* Check if each define_subst has corresponding define_subst_attr. */
2200 for (elem = define_subst_queue; elem ; elem = elem->next)
2202 for (elem_attr = define_subst_attr_queue;
2203 elem_attr;
2204 elem_attr = elem_attr->next)
2205 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2206 goto found;
2208 error_at (elem->loc,
2209 "%s: `define_subst' must have at least one "
2210 "corresponding `define_subst_attr'",
2211 XSTR (elem->data, 0));
2212 return;
2214 found:
2215 continue;
2218 for (elem = define_insn_queue; elem ; elem = elem->next)
2219 process_substs_on_one_elem (elem, define_insn_queue);
2220 for (elem = other_queue; elem ; elem = elem->next)
2222 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2223 continue;
2224 process_substs_on_one_elem (elem, other_queue);
2228 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2229 the top-level elements. */
2231 class gen_reader : public rtx_reader
2233 public:
2234 gen_reader () : rtx_reader () {}
2235 void handle_unknown_directive (file_location, const char *);
2238 void
2239 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2241 auto_vec<rtx, 32> subrtxs;
2242 if (!read_rtx (rtx_name, &subrtxs))
2243 return;
2245 rtx x;
2246 unsigned int i;
2247 FOR_EACH_VEC_ELT (subrtxs, i, x)
2248 process_rtx (x, loc);
2251 /* Comparison function for the mnemonic hash table. */
2253 static int
2254 htab_eq_string (const void *s1, const void *s2)
2256 return strcmp ((const char*)s1, (const char*)s2) == 0;
2259 /* Add mnemonic STR with length LEN to the mnemonic hash table
2260 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2261 and a permanent heap copy of STR is created. */
2263 static void
2264 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2266 char *new_str;
2267 void **slot;
2268 char *str_zero = (char*)alloca (len + 1);
2270 memcpy (str_zero, str, len);
2271 str_zero[len] = '\0';
2273 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2275 if (*slot)
2276 return;
2278 /* Not found; create a permanent copy and add it to the hash table. */
2279 new_str = XNEWVAR (char, len + 1);
2280 memcpy (new_str, str_zero, len + 1);
2281 *slot = new_str;
2284 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2285 table in MNEMONIC_HTAB.
2287 The mnemonics cannot be found if they are emitted using C code.
2289 If a mnemonic string contains ';' or a newline the string assumed
2290 to consist of more than a single instruction. The attribute value
2291 will then be set to the user defined default value. */
2293 static void
2294 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2296 const char *template_code, *cp;
2297 int i;
2298 int vec_len;
2299 rtx set_attr;
2300 char *attr_name;
2301 rtvec new_vec;
2303 template_code = XTMPL (insn, 3);
2305 /* Skip patterns which use C code to emit the template. */
2306 if (template_code[0] == '*')
2307 return;
2309 if (template_code[0] == '@')
2310 cp = &template_code[1];
2311 else
2312 cp = &template_code[0];
2314 for (i = 0; *cp; )
2316 const char *ep, *sp;
2317 size_t size = 0;
2319 while (ISSPACE (*cp))
2320 cp++;
2322 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2323 if (!ISSPACE (*ep))
2324 sp = ep + 1;
2326 if (i > 0)
2327 obstack_1grow (&string_obstack, ',');
2329 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2330 || (*cp >= 'a' && *cp <= 'z')))
2333 obstack_1grow (&string_obstack, *cp);
2334 cp++;
2335 size++;
2338 while (cp < sp)
2340 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2342 /* Don't set a value if there are more than one
2343 instruction in the string. */
2344 obstack_blank_fast (&string_obstack, -size);
2345 size = 0;
2347 cp = sp;
2348 break;
2350 cp++;
2352 if (size == 0)
2353 obstack_1grow (&string_obstack, '*');
2354 else
2355 add_mnemonic_string (mnemonic_htab,
2356 (char *) obstack_next_free (&string_obstack) - size,
2357 size);
2358 i++;
2361 /* An insn definition might emit an empty string. */
2362 if (obstack_object_size (&string_obstack) == 0)
2363 return;
2365 obstack_1grow (&string_obstack, '\0');
2367 set_attr = rtx_alloc (SET_ATTR);
2368 XSTR (set_attr, 1) = XOBFINISH (&string_obstack, char *);
2369 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2370 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2371 XSTR (set_attr, 0) = attr_name;
2373 if (!XVEC (insn, 4))
2374 vec_len = 0;
2375 else
2376 vec_len = XVECLEN (insn, 4);
2378 new_vec = rtvec_alloc (vec_len + 1);
2379 for (i = 0; i < vec_len; i++)
2380 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2381 RTVEC_ELT (new_vec, vec_len) = set_attr;
2382 XVEC (insn, 4) = new_vec;
2385 /* This function is called for the elements in the mnemonic hashtable
2386 and generates a comma separated list of the mnemonics. */
2388 static int
2389 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2391 obstack_grow (&string_obstack, (char*)*slot, strlen ((char*)*slot));
2392 obstack_1grow (&string_obstack, ',');
2393 return 1;
2396 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2397 insn definition in case the back end requests it by defining the
2398 mnemonic attribute. The values for the attribute will be extracted
2399 from the output patterns of the insn definitions as far as
2400 possible. */
2402 static void
2403 gen_mnemonic_attr (void)
2405 struct queue_elem *elem;
2406 rtx mnemonic_attr = NULL;
2407 htab_t mnemonic_htab;
2408 const char *str, *p;
2409 int i;
2411 if (have_error)
2412 return;
2414 /* Look for the DEFINE_ATTR for `mnemonic'. */
2415 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2416 if (GET_CODE (elem->data) == DEFINE_ATTR
2417 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2419 mnemonic_attr = elem->data;
2420 break;
2423 /* A (define_attr "mnemonic" "...") indicates that the back-end
2424 wants a mnemonic attribute to be generated. */
2425 if (!mnemonic_attr)
2426 return;
2428 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2429 htab_eq_string, 0, xcalloc, free);
2431 for (elem = define_insn_queue; elem; elem = elem->next)
2433 rtx insn = elem->data;
2434 bool found = false;
2436 /* Check if the insn definition already has
2437 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2438 if (XVEC (insn, 4))
2439 for (i = 0; i < XVECLEN (insn, 4); i++)
2441 rtx set_attr = XVECEXP (insn, 4, i);
2443 switch (GET_CODE (set_attr))
2445 case SET_ATTR:
2446 case SET_ATTR_ALTERNATIVE:
2447 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
2448 found = true;
2449 break;
2450 case SET:
2451 if (GET_CODE (SET_DEST (set_attr)) == ATTR
2452 && strcmp (XSTR (SET_DEST (set_attr), 0),
2453 MNEMONIC_ATTR_NAME) == 0)
2454 found = true;
2455 break;
2456 default:
2457 break;
2461 if (!found)
2462 gen_mnemonic_setattr (mnemonic_htab, insn);
2465 /* Add the user defined values to the hash table. */
2466 str = XSTR (mnemonic_attr, 1);
2467 while ((p = scan_comma_elt (&str)) != NULL)
2468 add_mnemonic_string (mnemonic_htab, p, str - p);
2470 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2472 /* Replace the last ',' with the zero end character. */
2473 *((char *)obstack_next_free (&string_obstack) - 1) = '\0';
2474 XSTR (mnemonic_attr, 1) = XOBFINISH (&string_obstack, char *);
2477 /* Check if there are DEFINE_ATTRs with the same name. */
2478 static void
2479 check_define_attr_duplicates ()
2481 struct queue_elem *elem;
2482 htab_t attr_htab;
2483 char * attr_name;
2484 void **slot;
2486 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2488 for (elem = define_attr_queue; elem; elem = elem->next)
2490 attr_name = xstrdup (XSTR (elem->data, 0));
2492 slot = htab_find_slot (attr_htab, attr_name, INSERT);
2494 /* Duplicate. */
2495 if (*slot)
2497 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
2498 htab_delete (attr_htab);
2499 return;
2502 *slot = attr_name;
2505 htab_delete (attr_htab);
2508 /* The entry point for initializing the reader. */
2510 rtx_reader *
2511 init_rtx_reader_args_cb (int argc, const char **argv,
2512 bool (*parse_opt) (const char *))
2514 /* Prepare to read input. */
2515 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2516 init_predicate_table ();
2517 obstack_init (rtl_obstack);
2519 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2520 insn_sequence_num = 1;
2522 /* These sequences are not used as indices, so can start at 1 also. */
2523 split_sequence_num = 1;
2524 peephole2_sequence_num = 1;
2526 gen_reader *reader = new gen_reader ();
2527 reader->read_md_files (argc, argv, parse_opt);
2529 if (define_attr_queue != NULL)
2530 check_define_attr_duplicates ();
2532 /* Process define_cond_exec patterns. */
2533 if (define_cond_exec_queue != NULL)
2534 process_define_cond_exec ();
2536 /* Process define_subst patterns. */
2537 if (define_subst_queue != NULL)
2538 process_define_subst ();
2540 if (define_attr_queue != NULL)
2541 gen_mnemonic_attr ();
2543 if (have_error)
2545 delete reader;
2546 return NULL;
2549 return reader;
2552 /* Programs that don't have their own options can use this entry point
2553 instead. */
2554 rtx_reader *
2555 init_rtx_reader_args (int argc, const char **argv)
2557 return init_rtx_reader_args_cb (argc, argv, 0);
2560 /* Try to read a single rtx from the file. Return true on success,
2561 describing it in *INFO. */
2563 bool
2564 read_md_rtx (md_rtx_info *info)
2566 int truth, *counter;
2567 rtx def;
2569 /* Discard insn patterns which we know can never match (because
2570 their C test is provably always false). If insn_elision is
2571 false, our caller needs to see all the patterns. Note that the
2572 elided patterns are never counted by the sequence numbering; it
2573 is the caller's responsibility, when insn_elision is false, not
2574 to use elided pattern numbers for anything. */
2577 struct queue_elem **queue, *elem;
2579 /* Read all patterns from a given queue before moving on to the next. */
2580 if (define_attr_queue != NULL)
2581 queue = &define_attr_queue;
2582 else if (define_pred_queue != NULL)
2583 queue = &define_pred_queue;
2584 else if (define_insn_queue != NULL)
2585 queue = &define_insn_queue;
2586 else if (other_queue != NULL)
2587 queue = &other_queue;
2588 else
2589 return false;
2591 elem = *queue;
2592 *queue = elem->next;
2593 def = elem->data;
2594 info->def = def;
2595 info->loc = elem->loc;
2596 free (elem);
2598 truth = maybe_eval_c_test (get_c_test (def));
2600 while (truth == 0 && insn_elision);
2602 /* Perform code-specific processing and pick the appropriate sequence
2603 number counter. */
2604 switch (GET_CODE (def))
2606 case DEFINE_INSN:
2607 case DEFINE_EXPAND:
2608 /* insn_sequence_num is used here so the name table will match caller's
2609 idea of insn numbering, whether or not elision is active. */
2610 record_insn_name (insn_sequence_num, XSTR (def, 0));
2612 /* Fall through. */
2613 case DEFINE_PEEPHOLE:
2614 counter = &insn_sequence_num;
2615 break;
2617 case DEFINE_SPLIT:
2618 counter = &split_sequence_num;
2619 break;
2621 case DEFINE_PEEPHOLE2:
2622 counter = &peephole2_sequence_num;
2623 break;
2625 default:
2626 counter = NULL;
2627 break;
2630 if (counter)
2632 info->index = *counter;
2633 if (truth != 0)
2634 *counter += 1;
2636 else
2637 info->index = -1;
2639 if (!rtx_locs)
2640 rtx_locs = new hash_map <rtx, file_location>;
2641 rtx_locs->put (info->def, info->loc);
2643 return true;
2646 /* Return the file location of DEFINE_* rtx X, which was previously
2647 returned by read_md_rtx. */
2648 file_location
2649 get_file_location (rtx x)
2651 gcc_assert (rtx_locs);
2652 file_location *entry = rtx_locs->get (x);
2653 gcc_assert (entry);
2654 return *entry;
2657 /* Return the number of possible INSN_CODEs. Only meaningful once the
2658 whole file has been processed. */
2659 unsigned int
2660 get_num_insn_codes ()
2662 return insn_sequence_num;
2665 /* Return the C test that says whether definition rtx DEF can be used,
2666 or "" if it can be used unconditionally. */
2668 const char *
2669 get_c_test (rtx x)
2671 switch (GET_CODE (x))
2673 case DEFINE_INSN:
2674 case DEFINE_EXPAND:
2675 case DEFINE_SUBST:
2676 return XSTR (x, 2);
2678 case DEFINE_SPLIT:
2679 case DEFINE_PEEPHOLE:
2680 case DEFINE_PEEPHOLE2:
2681 return XSTR (x, 1);
2683 default:
2684 return "";
2688 /* Helper functions for insn elision. */
2690 /* Compute a hash function of a c_test structure, which is keyed
2691 by its ->expr field. */
2692 hashval_t
2693 hash_c_test (const void *x)
2695 const struct c_test *a = (const struct c_test *) x;
2696 const unsigned char *base, *s = (const unsigned char *) a->expr;
2697 hashval_t hash;
2698 unsigned char c;
2699 unsigned int len;
2701 base = s;
2702 hash = 0;
2704 while ((c = *s++) != '\0')
2706 hash += c + (c << 17);
2707 hash ^= hash >> 2;
2710 len = s - base;
2711 hash += len + (len << 17);
2712 hash ^= hash >> 2;
2714 return hash;
2717 /* Compare two c_test expression structures. */
2719 cmp_c_test (const void *x, const void *y)
2721 const struct c_test *a = (const struct c_test *) x;
2722 const struct c_test *b = (const struct c_test *) y;
2724 return !strcmp (a->expr, b->expr);
2727 /* Given a string representing a C test expression, look it up in the
2728 condition_table and report whether or not its value is known
2729 at compile time. Returns a tristate: 1 for known true, 0 for
2730 known false, -1 for unknown. */
2732 maybe_eval_c_test (const char *expr)
2734 const struct c_test *test;
2735 struct c_test dummy;
2737 if (expr[0] == 0)
2738 return 1;
2740 dummy.expr = expr;
2741 test = (const struct c_test *)htab_find (condition_table, &dummy);
2742 if (!test)
2743 return -1;
2744 return test->value;
2747 /* Record the C test expression EXPR in the condition_table, with
2748 value VAL. Duplicates clobber previous entries. */
2750 void
2751 add_c_test (const char *expr, int value)
2753 struct c_test *test;
2755 if (expr[0] == 0)
2756 return;
2758 test = XNEW (struct c_test);
2759 test->expr = expr;
2760 test->value = value;
2762 *(htab_find_slot (condition_table, test, INSERT)) = test;
2765 /* For every C test, call CALLBACK with two arguments: a pointer to
2766 the condition structure and INFO. Stops when CALLBACK returns zero. */
2767 void
2768 traverse_c_tests (htab_trav callback, void *info)
2770 if (condition_table)
2771 htab_traverse (condition_table, callback, info);
2774 /* Helper functions for define_predicate and define_special_predicate
2775 processing. Shared between genrecog.c and genpreds.c. */
2777 static htab_t predicate_table;
2778 struct pred_data *first_predicate;
2779 static struct pred_data **last_predicate = &first_predicate;
2781 static hashval_t
2782 hash_struct_pred_data (const void *ptr)
2784 return htab_hash_string (((const struct pred_data *)ptr)->name);
2787 static int
2788 eq_struct_pred_data (const void *a, const void *b)
2790 return !strcmp (((const struct pred_data *)a)->name,
2791 ((const struct pred_data *)b)->name);
2794 struct pred_data *
2795 lookup_predicate (const char *name)
2797 struct pred_data key;
2798 key.name = name;
2799 return (struct pred_data *) htab_find (predicate_table, &key);
2802 /* Record that predicate PRED can accept CODE. */
2804 void
2805 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2807 if (!pred->codes[code])
2809 pred->num_codes++;
2810 pred->codes[code] = true;
2812 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2813 pred->allows_non_const = true;
2815 if (code != REG
2816 && code != SUBREG
2817 && code != MEM
2818 && code != CONCAT
2819 && code != PARALLEL
2820 && code != STRICT_LOW_PART
2821 && code != SCRATCH)
2822 pred->allows_non_lvalue = true;
2824 if (pred->num_codes == 1)
2825 pred->singleton = code;
2826 else if (pred->num_codes == 2)
2827 pred->singleton = UNKNOWN;
2831 void
2832 add_predicate (struct pred_data *pred)
2834 void **slot = htab_find_slot (predicate_table, pred, INSERT);
2835 if (*slot)
2837 error ("duplicate predicate definition for '%s'", pred->name);
2838 return;
2840 *slot = pred;
2841 *last_predicate = pred;
2842 last_predicate = &pred->next;
2845 /* This array gives the initial content of the predicate table. It
2846 has entries for all predicates defined in recog.c. */
2848 struct std_pred_table
2850 const char *name;
2851 bool special;
2852 bool allows_const_p;
2853 RTX_CODE codes[NUM_RTX_CODE];
2856 static const struct std_pred_table std_preds[] = {
2857 {"general_operand", false, true, {SUBREG, REG, MEM}},
2858 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
2859 ZERO_EXTEND, SIGN_EXTEND, AND}},
2860 {"register_operand", false, false, {SUBREG, REG}},
2861 {"pmode_register_operand", true, false, {SUBREG, REG}},
2862 {"scratch_operand", false, false, {SCRATCH, REG}},
2863 {"immediate_operand", false, true, {UNKNOWN}},
2864 {"const_int_operand", false, false, {CONST_INT}},
2865 #if TARGET_SUPPORTS_WIDE_INT
2866 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
2867 {"const_double_operand", false, false, {CONST_DOUBLE}},
2868 #else
2869 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2870 #endif
2871 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2872 {"nonmemory_operand", false, true, {SUBREG, REG}},
2873 {"push_operand", false, false, {MEM}},
2874 {"pop_operand", false, false, {MEM}},
2875 {"memory_operand", false, false, {SUBREG, MEM}},
2876 {"indirect_operand", false, false, {SUBREG, MEM}},
2877 {"ordered_comparison_operator", false, false, {EQ, NE,
2878 LE, LT, GE, GT,
2879 LEU, LTU, GEU, GTU}},
2880 {"comparison_operator", false, false, {EQ, NE,
2881 LE, LT, GE, GT,
2882 LEU, LTU, GEU, GTU,
2883 UNORDERED, ORDERED,
2884 UNEQ, UNGE, UNGT,
2885 UNLE, UNLT, LTGT}}
2887 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2889 /* Initialize the table of predicate definitions, starting with
2890 the information we have on generic predicates. */
2892 static void
2893 init_predicate_table (void)
2895 size_t i, j;
2896 struct pred_data *pred;
2898 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2899 eq_struct_pred_data, 0,
2900 xcalloc, free);
2902 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2904 pred = XCNEW (struct pred_data);
2905 pred->name = std_preds[i].name;
2906 pred->special = std_preds[i].special;
2908 for (j = 0; std_preds[i].codes[j] != 0; j++)
2909 add_predicate_code (pred, std_preds[i].codes[j]);
2911 if (std_preds[i].allows_const_p)
2912 for (j = 0; j < NUM_RTX_CODE; j++)
2913 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2914 add_predicate_code (pred, (enum rtx_code) j);
2916 add_predicate (pred);
2920 /* These functions allow linkage with print-rtl.c. Also, some generators
2921 like to annotate their output with insn names. */
2923 /* Holds an array of names indexed by insn_code_number. */
2924 static char **insn_name_ptr = 0;
2925 static int insn_name_ptr_size = 0;
2927 const char *
2928 get_insn_name (int code)
2930 if (code < insn_name_ptr_size)
2931 return insn_name_ptr[code];
2932 else
2933 return NULL;
2936 static void
2937 record_insn_name (int code, const char *name)
2939 static const char *last_real_name = "insn";
2940 static int last_real_code = 0;
2941 char *new_name;
2943 if (insn_name_ptr_size <= code)
2945 int new_size;
2946 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
2947 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
2948 memset (insn_name_ptr + insn_name_ptr_size, 0,
2949 sizeof (char *) * (new_size - insn_name_ptr_size));
2950 insn_name_ptr_size = new_size;
2953 if (!name || name[0] == '\0')
2955 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
2956 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
2958 else
2960 last_real_name = new_name = xstrdup (name);
2961 last_real_code = code;
2964 insn_name_ptr[code] = new_name;
2967 /* Make STATS describe the operands that appear in rtx X. */
2969 static void
2970 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
2972 RTX_CODE code;
2973 int i;
2974 int len;
2975 const char *fmt;
2977 if (x == NULL_RTX)
2978 return;
2980 code = GET_CODE (x);
2981 switch (code)
2983 case MATCH_OPERAND:
2984 case MATCH_OPERATOR:
2985 case MATCH_PARALLEL:
2986 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
2987 break;
2989 case MATCH_DUP:
2990 case MATCH_OP_DUP:
2991 case MATCH_PAR_DUP:
2992 stats->num_dups++;
2993 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
2994 break;
2996 case MATCH_SCRATCH:
2997 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
2998 break;
3000 default:
3001 break;
3004 fmt = GET_RTX_FORMAT (code);
3005 len = GET_RTX_LENGTH (code);
3006 for (i = 0; i < len; i++)
3008 if (fmt[i] == 'e' || fmt[i] == 'u')
3009 get_pattern_stats_1 (stats, XEXP (x, i));
3010 else if (fmt[i] == 'E')
3012 int j;
3013 for (j = 0; j < XVECLEN (x, i); j++)
3014 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3019 /* Make STATS describe the operands that appear in instruction pattern
3020 PATTERN. */
3022 void
3023 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3025 int i, len;
3027 stats->max_opno = -1;
3028 stats->max_dup_opno = -1;
3029 stats->max_scratch_opno = -1;
3030 stats->num_dups = 0;
3032 len = GET_NUM_ELEM (pattern);
3033 for (i = 0; i < len; i++)
3034 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3036 stats->num_generator_args = stats->max_opno + 1;
3037 stats->num_insn_operands = MAX (stats->max_opno,
3038 stats->max_scratch_opno) + 1;
3039 stats->num_operand_vars = MAX (stats->max_opno,
3040 MAX (stats->max_dup_opno,
3041 stats->max_scratch_opno)) + 1;
3044 /* Return the emit_* function that should be used for pattern X, or NULL
3045 if we can't pick a particular type at compile time and should instead
3046 fall back to "emit". */
3048 const char *
3049 get_emit_function (rtx x)
3051 switch (classify_insn (x))
3053 case INSN:
3054 return "emit_insn";
3056 case CALL_INSN:
3057 return "emit_call_insn";
3059 case JUMP_INSN:
3060 return "emit_jump_insn";
3062 case UNKNOWN:
3063 return NULL;
3065 default:
3066 gcc_unreachable ();
3070 /* Return true if we must emit a barrier after pattern X. */
3072 bool
3073 needs_barrier_p (rtx x)
3075 return (GET_CODE (x) == SET
3076 && GET_CODE (SET_DEST (x)) == PC
3077 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3080 #define NS "NULL"
3081 #define ZS "'\\0'"
3082 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3083 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3084 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3085 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3086 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3087 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3088 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3089 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3090 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3091 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3092 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3094 /* An array of all optabs. Note that the same optab can appear more
3095 than once, with a different pattern. */
3096 optab_def optabs[] = {
3097 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3098 #include "optabs.def"
3101 /* The number of entries in optabs[]. */
3102 unsigned int num_optabs = ARRAY_SIZE (optabs);
3104 #undef OPTAB_CL
3105 #undef OPTAB_CX
3106 #undef OPTAB_CD
3107 #undef OPTAB_NL
3108 #undef OPTAB_NC
3109 #undef OPTAB_NX
3110 #undef OPTAB_VL
3111 #undef OPTAB_VC
3112 #undef OPTAB_VX
3113 #undef OPTAB_DC
3114 #undef OPTAB_D
3116 /* Return true if instruction NAME matches pattern PAT, storing information
3117 about the match in P if so. */
3119 static bool
3120 match_pattern (optab_pattern *p, const char *name, const char *pat)
3122 bool force_float = false;
3123 bool force_int = false;
3124 bool force_partial_int = false;
3125 bool force_fixed = false;
3127 if (pat == NULL)
3128 return false;
3129 for (; ; ++pat)
3131 if (*pat != '$')
3133 if (*pat != *name++)
3134 return false;
3135 if (*pat == '\0')
3136 return true;
3137 continue;
3139 switch (*++pat)
3141 case 'I':
3142 force_int = 1;
3143 break;
3144 case 'P':
3145 force_partial_int = 1;
3146 break;
3147 case 'F':
3148 force_float = 1;
3149 break;
3150 case 'Q':
3151 force_fixed = 1;
3152 break;
3154 case 'a':
3155 case 'b':
3157 int i;
3159 /* This loop will stop at the first prefix match, so
3160 look through the modes in reverse order, in case
3161 there are extra CC modes and CC is a prefix of the
3162 CC modes (as it should be). */
3163 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3165 const char *p, *q;
3166 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3167 if (TOLOWER (*p) != *q)
3168 break;
3169 if (*p == 0
3170 && (! force_int || mode_class[i] == MODE_INT
3171 || mode_class[i] == MODE_VECTOR_INT)
3172 && (! force_partial_int
3173 || mode_class[i] == MODE_INT
3174 || mode_class[i] == MODE_PARTIAL_INT
3175 || mode_class[i] == MODE_VECTOR_INT)
3176 && (! force_float
3177 || mode_class[i] == MODE_FLOAT
3178 || mode_class[i] == MODE_DECIMAL_FLOAT
3179 || mode_class[i] == MODE_COMPLEX_FLOAT
3180 || mode_class[i] == MODE_VECTOR_FLOAT)
3181 && (! force_fixed
3182 || mode_class[i] == MODE_FRACT
3183 || mode_class[i] == MODE_UFRACT
3184 || mode_class[i] == MODE_ACCUM
3185 || mode_class[i] == MODE_UACCUM
3186 || mode_class[i] == MODE_VECTOR_FRACT
3187 || mode_class[i] == MODE_VECTOR_UFRACT
3188 || mode_class[i] == MODE_VECTOR_ACCUM
3189 || mode_class[i] == MODE_VECTOR_UACCUM))
3190 break;
3193 if (i < 0)
3194 return false;
3195 name += strlen (GET_MODE_NAME (i));
3196 if (*pat == 'a')
3197 p->m1 = i;
3198 else
3199 p->m2 = i;
3201 force_int = false;
3202 force_partial_int = false;
3203 force_float = false;
3204 force_fixed = false;
3206 break;
3208 default:
3209 gcc_unreachable ();
3214 /* Return true if NAME is the name of an optab, describing it in P if so. */
3216 bool
3217 find_optab (optab_pattern *p, const char *name)
3219 if (*name == 0 || *name == '*')
3220 return false;
3222 /* See if NAME matches one of the patterns we have for the optabs
3223 we know about. */
3224 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3226 p->m1 = p->m2 = 0;
3227 if (match_pattern (p, name, optabs[pindex].pattern))
3229 p->name = name;
3230 p->op = optabs[pindex].op;
3231 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
3232 return true;
3235 return false;