gcc/
[official-gcc.git] / gcc / gensupport.c
blob0eb45919ec83af8f4936d75ea90c331e1a34eeab
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;
1042 case 'E':
1043 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1044 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1045 return 0;
1046 break;
1048 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1049 break;
1051 default:
1052 gcc_unreachable ();
1055 return 1;
1058 /* Determine how many alternatives there are in INSN, and how many
1059 operands. */
1061 static void
1062 collect_insn_data (rtx pattern, int *palt, int *pmax)
1064 const char *fmt;
1065 enum rtx_code code;
1066 int i, j, len;
1068 code = GET_CODE (pattern);
1069 switch (code)
1071 case MATCH_OPERAND:
1072 case MATCH_SCRATCH:
1073 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1074 *palt = (i > *palt ? i : *palt);
1075 /* Fall through. */
1077 case MATCH_OPERATOR:
1078 case MATCH_PARALLEL:
1079 i = XINT (pattern, 0);
1080 if (i > *pmax)
1081 *pmax = i;
1082 break;
1084 default:
1085 break;
1088 fmt = GET_RTX_FORMAT (code);
1089 len = GET_RTX_LENGTH (code);
1090 for (i = 0; i < len; i++)
1092 switch (fmt[i])
1094 case 'e': case 'u':
1095 collect_insn_data (XEXP (pattern, i), palt, pmax);
1096 break;
1098 case 'V':
1099 if (XVEC (pattern, i) == NULL)
1100 break;
1101 /* Fall through. */
1102 case 'E':
1103 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1104 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1105 break;
1107 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1108 break;
1110 default:
1111 gcc_unreachable ();
1116 static rtx
1117 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1118 file_location loc)
1120 const char *fmt;
1121 enum rtx_code code;
1122 int i, j, len;
1124 code = GET_CODE (pattern);
1125 switch (code)
1127 case MATCH_OPERAND:
1129 const char *c = XSTR (pattern, 2);
1131 if (n_alternatives (c) != 1)
1133 error_at (loc, "too many alternatives for operand %d",
1134 XINT (pattern, 0));
1135 return NULL;
1138 /* Replicate C as needed to fill out ALT alternatives. */
1139 if (c && *c && alt > 1)
1141 size_t c_len = strlen (c);
1142 size_t len = alt * (c_len + 1);
1143 char *new_c = XNEWVEC (char, len);
1145 memcpy (new_c, c, c_len);
1146 for (i = 1; i < alt; ++i)
1148 new_c[i * (c_len + 1) - 1] = ',';
1149 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1151 new_c[len - 1] = '\0';
1152 XSTR (pattern, 2) = new_c;
1155 /* Fall through. */
1157 case MATCH_OPERATOR:
1158 case MATCH_SCRATCH:
1159 case MATCH_PARALLEL:
1160 XINT (pattern, 0) += max_op;
1161 break;
1163 default:
1164 break;
1167 fmt = GET_RTX_FORMAT (code);
1168 len = GET_RTX_LENGTH (code);
1169 for (i = 0; i < len; i++)
1171 rtx r;
1173 switch (fmt[i])
1175 case 'e': case 'u':
1176 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1177 if (r == NULL)
1178 return r;
1179 break;
1181 case 'E':
1182 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1184 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1185 alt, max_op, loc);
1186 if (r == NULL)
1187 return r;
1189 break;
1191 case 'i': case 'r': case 'w': case '0': case 's':
1192 break;
1194 default:
1195 gcc_unreachable ();
1199 return pattern;
1202 /* Duplicate constraints in PATTERN. If pattern is from original
1203 rtl-template, we need to duplicate each alternative - for that we
1204 need to use duplicate_each_alternative () as a functor ALTER.
1205 If pattern is from output-pattern of define_subst, we need to
1206 duplicate constraints in another way - with duplicate_alternatives ().
1207 N_DUP is multiplication factor. */
1208 static rtx
1209 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1211 const char *fmt;
1212 enum rtx_code code;
1213 int i, j, len;
1215 code = GET_CODE (pattern);
1216 switch (code)
1218 case MATCH_OPERAND:
1219 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1220 break;
1222 default:
1223 break;
1226 fmt = GET_RTX_FORMAT (code);
1227 len = GET_RTX_LENGTH (code);
1228 for (i = 0; i < len; i++)
1230 rtx r;
1232 switch (fmt[i])
1234 case 'e': case 'u':
1235 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1236 if (r == NULL)
1237 return r;
1238 break;
1240 case 'E':
1241 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1243 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1244 if (r == NULL)
1245 return r;
1247 break;
1249 case 'i': case 'r': case 'w': case '0': case 's':
1250 break;
1252 default:
1253 break;
1257 return pattern;
1260 static const char *
1261 alter_test_for_insn (struct queue_elem *ce_elem,
1262 struct queue_elem *insn_elem)
1264 return join_c_conditions (XSTR (ce_elem->data, 1),
1265 XSTR (insn_elem->data, 2));
1268 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1269 to take "ce_enabled" into account. Return the new expression. */
1270 static rtx
1271 modify_attr_enabled_ce (rtx val)
1273 rtx eq_attr, str;
1274 rtx ite;
1275 eq_attr = rtx_alloc (EQ_ATTR);
1276 ite = rtx_alloc (IF_THEN_ELSE);
1277 str = rtx_alloc (CONST_STRING);
1279 XSTR (eq_attr, 0) = "ce_enabled";
1280 XSTR (eq_attr, 1) = "yes";
1281 XSTR (str, 0) = "no";
1282 XEXP (ite, 0) = eq_attr;
1283 XEXP (ite, 1) = val;
1284 XEXP (ite, 2) = str;
1286 return ite;
1289 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1290 from a define_insn pattern. We must modify the "predicable" attribute
1291 to be named "ce_enabled", and also change any "enabled" attribute that's
1292 present so that it takes ce_enabled into account.
1293 We rely on the fact that INSN was created with copy_rtx, and modify data
1294 in-place. */
1296 static void
1297 alter_attrs_for_insn (rtx insn)
1299 static bool global_changes_made = false;
1300 rtvec vec = XVEC (insn, 4);
1301 rtvec new_vec;
1302 rtx val, set;
1303 int num_elem;
1304 int predicable_idx = -1;
1305 int enabled_idx = -1;
1306 int i;
1308 if (! vec)
1309 return;
1311 num_elem = GET_NUM_ELEM (vec);
1312 for (i = num_elem - 1; i >= 0; --i)
1314 rtx sub = RTVEC_ELT (vec, i);
1315 switch (GET_CODE (sub))
1317 case SET_ATTR:
1318 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1320 predicable_idx = i;
1321 XSTR (sub, 0) = "ce_enabled";
1323 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1325 enabled_idx = i;
1326 XSTR (sub, 0) = "nonce_enabled";
1328 break;
1330 case SET_ATTR_ALTERNATIVE:
1331 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1332 /* We already give an error elsewhere. */
1333 return;
1334 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1336 enabled_idx = i;
1337 XSTR (sub, 0) = "nonce_enabled";
1339 break;
1341 case SET:
1342 if (GET_CODE (SET_DEST (sub)) != ATTR)
1343 break;
1344 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1346 sub = SET_SRC (sub);
1347 if (GET_CODE (sub) == CONST_STRING)
1349 predicable_idx = i;
1350 XSTR (sub, 0) = "ce_enabled";
1352 else
1353 /* We already give an error elsewhere. */
1354 return;
1355 break;
1357 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1359 enabled_idx = i;
1360 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1362 break;
1364 default:
1365 gcc_unreachable ();
1368 if (predicable_idx == -1)
1369 return;
1371 if (!global_changes_made)
1373 struct queue_elem *elem;
1375 global_changes_made = true;
1376 add_define_attr ("ce_enabled");
1377 add_define_attr ("nonce_enabled");
1379 for (elem = define_attr_queue; elem ; elem = elem->next)
1380 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1382 XEXP (elem->data, 2)
1383 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1386 if (enabled_idx == -1)
1387 return;
1389 new_vec = rtvec_alloc (num_elem + 1);
1390 for (i = 0; i < num_elem; i++)
1391 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1392 val = rtx_alloc (IF_THEN_ELSE);
1393 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1394 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1395 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1396 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1397 XSTR (XEXP (val, 0), 1) = "yes";
1398 XSTR (XEXP (val, 1), 0) = "yes";
1399 XSTR (XEXP (val, 2), 0) = "no";
1400 set = rtx_alloc (SET);
1401 SET_DEST (set) = rtx_alloc (ATTR);
1402 XSTR (SET_DEST (set), 0) = "enabled";
1403 SET_SRC (set) = modify_attr_enabled_ce (val);
1404 RTVEC_ELT (new_vec, i) = set;
1405 XVEC (insn, 4) = new_vec;
1408 /* As number of constraints is changed after define_subst, we need to
1409 process attributes as well - we need to duplicate them the same way
1410 that we duplicated constraints in original pattern
1411 ELEM is a queue element, containing our rtl-template,
1412 N_DUP - multiplication factor. */
1413 static void
1414 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
1416 rtvec vec = XVEC (elem->data, 4);
1417 int num_elem;
1418 int i;
1420 if (n_dup < 2 || ! vec)
1421 return;
1423 num_elem = GET_NUM_ELEM (vec);
1424 for (i = num_elem - 1; i >= 0; --i)
1426 rtx sub = RTVEC_ELT (vec, i);
1427 switch (GET_CODE (sub))
1429 case SET_ATTR:
1430 if (strchr (XSTR (sub, 1), ',') != NULL)
1431 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1432 break;
1434 case SET_ATTR_ALTERNATIVE:
1435 case SET:
1436 error_at (elem->loc,
1437 "%s: `define_subst' does not support attributes "
1438 "assigned by `set' and `set_attr_alternative'",
1439 XSTR (elem->data, 0));
1440 return;
1442 default:
1443 gcc_unreachable ();
1448 /* Adjust all of the operand numbers in SRC to match the shift they'll
1449 get from an operand displacement of DISP. Return a pointer after the
1450 adjusted string. */
1452 static char *
1453 shift_output_template (char *dest, const char *src, int disp)
1455 while (*src)
1457 char c = *src++;
1458 *dest++ = c;
1459 if (c == '%')
1461 c = *src++;
1462 if (ISDIGIT ((unsigned char) c))
1463 c += disp;
1464 else if (ISALPHA (c))
1466 *dest++ = c;
1467 c = *src++ + disp;
1469 *dest++ = c;
1473 return dest;
1476 static const char *
1477 alter_output_for_insn (struct queue_elem *ce_elem,
1478 struct queue_elem *insn_elem,
1479 int alt, int max_op)
1481 const char *ce_out, *insn_out;
1482 char *result, *p;
1483 size_t len, ce_len, insn_len;
1485 /* ??? Could coordinate with genoutput to not duplicate code here. */
1487 ce_out = XSTR (ce_elem->data, 2);
1488 insn_out = XTMPL (insn_elem->data, 3);
1489 if (!ce_out || *ce_out == '\0')
1490 return insn_out;
1492 ce_len = strlen (ce_out);
1493 insn_len = strlen (insn_out);
1495 if (*insn_out == '*')
1496 /* You must take care of the predicate yourself. */
1497 return insn_out;
1499 if (*insn_out == '@')
1501 len = (ce_len + 1) * alt + insn_len + 1;
1502 p = result = XNEWVEC (char, len);
1507 *p++ = *insn_out++;
1508 while (ISSPACE ((unsigned char) *insn_out));
1510 if (*insn_out != '#')
1512 p = shift_output_template (p, ce_out, max_op);
1513 *p++ = ' ';
1517 *p++ = *insn_out++;
1518 while (*insn_out && *insn_out != '\n');
1520 while (*insn_out);
1521 *p = '\0';
1523 else
1525 len = ce_len + 1 + insn_len + 1;
1526 result = XNEWVEC (char, len);
1528 p = shift_output_template (result, ce_out, max_op);
1529 *p++ = ' ';
1530 memcpy (p, insn_out, insn_len + 1);
1533 return result;
1536 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1537 string, duplicated N_DUP times. */
1539 static const char *
1540 duplicate_alternatives (const char * str, int n_dup)
1542 int i, len, new_len;
1543 char *result, *sp;
1544 const char *cp;
1546 if (n_dup < 2)
1547 return str;
1549 while (ISSPACE (*str))
1550 str++;
1552 if (*str == '\0')
1553 return str;
1555 cp = str;
1556 len = strlen (str);
1557 new_len = (len + 1) * n_dup;
1559 sp = result = XNEWVEC (char, new_len);
1561 /* Global modifier characters mustn't be duplicated: skip if found. */
1562 if (*cp == '=' || *cp == '+' || *cp == '%')
1564 *sp++ = *cp++;
1565 len--;
1568 /* Copy original constraints N_DUP times. */
1569 for (i = 0; i < n_dup; i++, sp += len+1)
1571 memcpy (sp, cp, len);
1572 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1575 return result;
1578 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1579 each alternative from the original string is duplicated N_DUP times. */
1580 static const char *
1581 duplicate_each_alternative (const char * str, int n_dup)
1583 int i, len, new_len;
1584 char *result, *sp, *ep, *cp;
1586 if (n_dup < 2)
1587 return str;
1589 while (ISSPACE (*str))
1590 str++;
1592 if (*str == '\0')
1593 return str;
1595 cp = xstrdup (str);
1597 new_len = (strlen (cp) + 1) * n_dup;
1599 sp = result = XNEWVEC (char, new_len);
1601 /* Global modifier characters mustn't be duplicated: skip if found. */
1602 if (*cp == '=' || *cp == '+' || *cp == '%')
1603 *sp++ = *cp++;
1607 if ((ep = strchr (cp, ',')) != NULL)
1608 *ep++ = '\0';
1609 len = strlen (cp);
1611 /* Copy a constraint N_DUP times. */
1612 for (i = 0; i < n_dup; i++, sp += len + 1)
1614 memcpy (sp, cp, len);
1615 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1618 cp = ep;
1620 while (cp != NULL);
1622 return result;
1625 /* Alter the output of INSN whose pattern was modified by
1626 DEFINE_SUBST. We must replicate output strings according
1627 to the new number of alternatives ALT in substituted pattern.
1628 If ALT equals 1, output has one alternative or defined by C
1629 code, then output is returned without any changes. */
1631 static const char *
1632 alter_output_for_subst_insn (rtx insn, int alt)
1634 const char *insn_out, *sp ;
1635 char *old_out, *new_out, *cp;
1636 int i, j, new_len;
1638 insn_out = XTMPL (insn, 3);
1640 if (alt < 2 || *insn_out == '*' || *insn_out != '@')
1641 return insn_out;
1643 old_out = XNEWVEC (char, strlen (insn_out)),
1644 sp = insn_out;
1646 while (ISSPACE (*sp) || *sp == '@')
1647 sp++;
1649 for (i = 0; *sp;)
1650 old_out[i++] = *sp++;
1652 new_len = alt * (i + 1) + 1;
1654 new_out = XNEWVEC (char, new_len);
1655 new_out[0] = '@';
1657 for (j = 0, cp = new_out + 1; j < alt; j++, cp += i + 1)
1659 memcpy (cp, old_out, i);
1660 *(cp+i) = (j == alt - 1) ? '\0' : '\n';
1663 return new_out;
1666 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1668 static void
1669 process_one_cond_exec (struct queue_elem *ce_elem)
1671 struct queue_elem *insn_elem;
1672 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1674 int alternatives, max_operand;
1675 rtx pred, insn, pattern, split;
1676 char *new_name;
1677 int i;
1679 if (! is_predicable (insn_elem))
1680 continue;
1682 alternatives = 1;
1683 max_operand = -1;
1684 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1685 max_operand += 1;
1687 if (XVECLEN (ce_elem->data, 0) != 1)
1689 error_at (ce_elem->loc, "too many patterns in predicate");
1690 return;
1693 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1694 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1695 ce_elem->loc);
1696 if (pred == NULL)
1697 return;
1699 /* Construct a new pattern for the new insn. */
1700 insn = copy_rtx (insn_elem->data);
1701 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1702 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1703 XSTR (insn, 0) = new_name;
1704 pattern = rtx_alloc (COND_EXEC);
1705 XEXP (pattern, 0) = pred;
1706 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
1707 XVEC (insn, 1) = rtvec_alloc (1);
1708 XVECEXP (insn, 1, 0) = pattern;
1710 if (XVEC (ce_elem->data, 3) != NULL)
1712 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
1713 + XVECLEN (ce_elem->data, 3));
1714 int i = 0;
1715 int j = 0;
1716 for (i = 0; i < XVECLEN (insn, 4); i++)
1717 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
1719 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
1720 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
1722 XVEC (insn, 4) = attributes;
1725 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1726 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1727 alternatives, max_operand);
1728 alter_attrs_for_insn (insn);
1730 /* Put the new pattern on the `other' list so that it
1731 (a) is not reprocessed by other define_cond_exec patterns
1732 (b) appears after all normal define_insn patterns.
1734 ??? B is debatable. If one has normal insns that match
1735 cond_exec patterns, they will be preferred over these
1736 generated patterns. Whether this matters in practice, or if
1737 it's a good thing, or whether we should thread these new
1738 patterns into the define_insn chain just after their generator
1739 is something we'll have to experiment with. */
1741 queue_pattern (insn, &other_tail, insn_elem->loc);
1743 if (!insn_elem->split)
1744 continue;
1746 /* If the original insn came from a define_insn_and_split,
1747 generate a new split to handle the predicated insn. */
1748 split = copy_rtx (insn_elem->split->data);
1749 /* Predicate the pattern matched by the split. */
1750 pattern = rtx_alloc (COND_EXEC);
1751 XEXP (pattern, 0) = pred;
1752 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
1753 XVEC (split, 0) = rtvec_alloc (1);
1754 XVECEXP (split, 0, 0) = pattern;
1756 /* Predicate all of the insns generated by the split. */
1757 for (i = 0; i < XVECLEN (split, 2); i++)
1759 pattern = rtx_alloc (COND_EXEC);
1760 XEXP (pattern, 0) = pred;
1761 XEXP (pattern, 1) = XVECEXP (split, 2, i);
1762 XVECEXP (split, 2, i) = pattern;
1764 /* Add the new split to the queue. */
1765 queue_pattern (split, &other_tail, insn_elem->split->loc);
1769 /* Try to apply define_substs to the given ELEM.
1770 Only define_substs, specified via attributes would be applied.
1771 If attribute, requiring define_subst, is set, but no define_subst
1772 was applied, ELEM would be deleted. */
1774 static void
1775 process_substs_on_one_elem (struct queue_elem *elem,
1776 struct queue_elem *queue)
1778 struct queue_elem *subst_elem;
1779 int i, j, patterns_match;
1781 for (subst_elem = define_subst_queue;
1782 subst_elem; subst_elem = subst_elem->next)
1784 int alternatives, alternatives_subst;
1785 rtx subst_pattern;
1786 rtvec subst_pattern_vec;
1788 if (!has_subst_attribute (elem, subst_elem))
1789 continue;
1791 /* Compare original rtl-pattern from define_insn with input
1792 pattern from define_subst.
1793 Also, check if numbers of alternatives are the same in all
1794 match_operands. */
1795 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1796 continue;
1797 patterns_match = 1;
1798 alternatives = -1;
1799 alternatives_subst = -1;
1800 for (j = 0; j < XVECLEN (elem->data, 1); j++)
1802 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1803 XVECEXP (subst_elem->data, 1, j),
1804 subst_elem->loc))
1806 patterns_match = 0;
1807 break;
1810 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1811 &alternatives, subst_elem->loc))
1813 patterns_match = 0;
1814 break;
1818 /* Check if numbers of alternatives are the same in all
1819 match_operands in output template of define_subst. */
1820 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1822 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1823 &alternatives_subst,
1824 subst_elem->loc))
1826 patterns_match = 0;
1827 break;
1831 if (!patterns_match)
1832 continue;
1834 /* Clear array in which we save occupied indexes of operands. */
1835 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1837 /* Create a pattern, based on the output one from define_subst. */
1838 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1839 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1841 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1843 /* Duplicate constraints in substitute-pattern. */
1844 subst_pattern = alter_constraints (subst_pattern, alternatives,
1845 duplicate_each_alternative);
1847 subst_pattern = adjust_operands_numbers (subst_pattern);
1849 /* Substitute match_dup and match_op_dup in the new pattern and
1850 duplicate constraints. */
1851 subst_pattern = subst_dup (subst_pattern, alternatives,
1852 alternatives_subst);
1854 replace_duplicating_operands_in_pattern (subst_pattern);
1856 /* We don't need any constraints in DEFINE_EXPAND. */
1857 if (GET_CODE (elem->data) == DEFINE_EXPAND)
1858 remove_constraints (subst_pattern);
1860 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1862 XVEC (elem->data, 1) = subst_pattern_vec;
1864 for (i = 0; i < MAX_OPERANDS; i++)
1865 match_operand_entries_in_pattern[i] = NULL;
1867 if (GET_CODE (elem->data) == DEFINE_INSN)
1869 XTMPL (elem->data, 3) =
1870 alter_output_for_subst_insn (elem->data, alternatives_subst);
1871 alter_attrs_for_subst_insn (elem, alternatives_subst);
1874 /* Recalculate condition, joining conditions from original and
1875 DEFINE_SUBST input patterns. */
1876 XSTR (elem->data, 2) = 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);
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)
1889 if (has_subst_attribute (elem, subst_elem))
1891 remove_from_queue (elem, &queue);
1892 return;
1897 /* This is a subroutine of mark_operands_used_in_match_dup.
1898 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1899 static void
1900 mark_operands_from_match_dup (rtx pattern)
1902 const char *fmt;
1903 int i, j, len, opno;
1905 if (GET_CODE (pattern) == MATCH_OPERAND
1906 || GET_CODE (pattern) == MATCH_OPERATOR
1907 || GET_CODE (pattern) == MATCH_PARALLEL)
1909 opno = XINT (pattern, 0);
1910 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1911 used_operands_numbers [opno] = 1;
1913 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1914 len = GET_RTX_LENGTH (GET_CODE (pattern));
1915 for (i = 0; i < len; i++)
1917 switch (fmt[i])
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;
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. */
1934 static void
1935 mark_operands_used_in_match_dup (rtx pattern)
1937 const char *fmt;
1938 int i, j, len, opno;
1940 if (GET_CODE (pattern) == MATCH_DUP)
1942 opno = XINT (pattern, 0);
1943 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1944 mark_operands_from_match_dup (operand_data[opno]);
1945 return;
1947 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1948 len = GET_RTX_LENGTH (GET_CODE (pattern));
1949 for (i = 0; i < len; i++)
1951 switch (fmt[i])
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;
1964 /* This is subroutine of renumerate_operands_in_pattern.
1965 It finds first not-occupied operand-index. */
1966 static int
1967 find_first_unused_number_of_operand ()
1969 int i;
1970 for (i = 0; i < MAX_OPERANDS; i++)
1971 if (!used_operands_numbers[i])
1972 return i;
1973 return MAX_OPERANDS;
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. */
1980 static void
1981 renumerate_operands_in_pattern (rtx pattern)
1983 const char *fmt;
1984 enum rtx_code code;
1985 int i, j, len, new_opno;
1986 code = GET_CODE (pattern);
1988 if (code == MATCH_OPERAND
1989 || code == MATCH_OPERATOR)
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;
1997 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1998 len = GET_RTX_LENGTH (GET_CODE (pattern));
1999 for (i = 0; i < len; i++)
2001 switch (fmt[i])
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;
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. */
2022 static rtx
2023 adjust_operands_numbers (rtx pattern)
2025 mark_operands_used_in_match_dup (pattern);
2027 renumerate_operands_in_pattern (pattern);
2029 return pattern;
2032 /* Generate RTL expression
2033 (match_dup OPNO)
2035 static rtx
2036 generate_match_dup (int opno)
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;
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. */
2051 static rtx
2052 replace_duplicating_operands_in_pattern (rtx pattern)
2054 const char *fmt;
2055 int i, j, len, opno;
2056 rtx mdup;
2058 if (GET_CODE (pattern) == MATCH_OPERAND)
2060 opno = XINT (pattern, 0);
2061 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2062 if (match_operand_entries_in_pattern[opno] == NULL)
2064 match_operand_entries_in_pattern[opno] = pattern;
2065 return NULL;
2067 else
2069 /* Compare predicates before replacing with match_dup. */
2070 if (strcmp (XSTR (pattern, 1),
2071 XSTR (match_operand_entries_in_pattern[opno], 1)))
2073 error ("duplicated match_operands with different predicates were"
2074 " found.");
2075 return NULL;
2077 return generate_match_dup (opno);
2080 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2081 len = GET_RTX_LENGTH (GET_CODE (pattern));
2082 for (i = 0; i < len; i++)
2084 switch (fmt[i])
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)
2094 mdup =
2095 replace_duplicating_operands_in_pattern (XVECEXP
2096 (pattern, i, j));
2097 if (mdup)
2098 XVECEXP (pattern, i, j) = mdup;
2100 break;
2103 return NULL;
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. */
2115 static rtx
2116 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2118 const char *fmt;
2119 enum rtx_code code;
2120 int i, j, len, opno;
2122 code = GET_CODE (pattern);
2123 switch (code)
2125 case MATCH_DUP:
2126 case MATCH_OP_DUP:
2127 opno = XINT (pattern, 0);
2129 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2131 if (operand_data[opno])
2133 pattern = copy_rtx (operand_data[opno]);
2135 /* Duplicate constraints. */
2136 pattern = alter_constraints (pattern, n_subst_alt,
2137 duplicate_alternatives);
2139 break;
2141 default:
2142 break;
2145 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2146 len = GET_RTX_LENGTH (GET_CODE (pattern));
2147 for (i = 0; i < len; i++)
2149 switch (fmt[i])
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 case 'E':
2160 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2161 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2162 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2163 n_alt, n_subst_alt);
2164 break;
2166 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2167 break;
2169 default:
2170 gcc_unreachable ();
2173 return pattern;
2176 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2177 patterns appropriately. */
2179 static void
2180 process_define_cond_exec (void)
2182 struct queue_elem *elem;
2184 identify_predicable_attribute ();
2185 if (have_error)
2186 return;
2188 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2189 process_one_cond_exec (elem);
2192 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2193 DEFINE_EXPAND patterns appropriately. */
2195 static void
2196 process_define_subst (void)
2198 struct queue_elem *elem, *elem_attr;
2200 /* Check if each define_subst has corresponding define_subst_attr. */
2201 for (elem = define_subst_queue; elem ; elem = elem->next)
2203 for (elem_attr = define_subst_attr_queue;
2204 elem_attr;
2205 elem_attr = elem_attr->next)
2206 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2207 goto found;
2209 error_at (elem->loc,
2210 "%s: `define_subst' must have at least one "
2211 "corresponding `define_subst_attr'",
2212 XSTR (elem->data, 0));
2213 return;
2215 found:
2216 continue;
2219 for (elem = define_insn_queue; elem ; elem = elem->next)
2220 process_substs_on_one_elem (elem, define_insn_queue);
2221 for (elem = other_queue; elem ; elem = elem->next)
2223 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2224 continue;
2225 process_substs_on_one_elem (elem, other_queue);
2229 /* A read_md_files callback for reading an rtx. */
2231 static void
2232 rtx_handle_directive (file_location loc, const char *rtx_name)
2234 auto_vec<rtx, 32> subrtxs;
2235 if (!read_rtx (rtx_name, &subrtxs))
2236 return;
2238 rtx x;
2239 unsigned int i;
2240 FOR_EACH_VEC_ELT (subrtxs, i, x)
2241 process_rtx (x, loc);
2244 /* Comparison function for the mnemonic hash table. */
2246 static int
2247 htab_eq_string (const void *s1, const void *s2)
2249 return strcmp ((const char*)s1, (const char*)s2) == 0;
2252 /* Add mnemonic STR with length LEN to the mnemonic hash table
2253 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2254 and a permanent heap copy of STR is created. */
2256 static void
2257 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2259 char *new_str;
2260 void **slot;
2261 char *str_zero = (char*)alloca (len + 1);
2263 memcpy (str_zero, str, len);
2264 str_zero[len] = '\0';
2266 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2268 if (*slot)
2269 return;
2271 /* Not found; create a permanent copy and add it to the hash table. */
2272 new_str = XNEWVAR (char, len + 1);
2273 memcpy (new_str, str_zero, len + 1);
2274 *slot = new_str;
2277 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2278 table in MNEMONIC_HTAB.
2280 The mnemonics cannot be found if they are emitted using C code.
2282 If a mnemonic string contains ';' or a newline the string assumed
2283 to consist of more than a single instruction. The attribute value
2284 will then be set to the user defined default value. */
2286 static void
2287 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2289 const char *template_code, *cp;
2290 int i;
2291 int vec_len;
2292 rtx set_attr;
2293 char *attr_name;
2294 rtvec new_vec;
2296 template_code = XTMPL (insn, 3);
2298 /* Skip patterns which use C code to emit the template. */
2299 if (template_code[0] == '*')
2300 return;
2302 if (template_code[0] == '@')
2303 cp = &template_code[1];
2304 else
2305 cp = &template_code[0];
2307 for (i = 0; *cp; )
2309 const char *ep, *sp;
2310 size_t size = 0;
2312 while (ISSPACE (*cp))
2313 cp++;
2315 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2316 if (!ISSPACE (*ep))
2317 sp = ep + 1;
2319 if (i > 0)
2320 obstack_1grow (&string_obstack, ',');
2322 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2323 || (*cp >= 'a' && *cp <= 'z')))
2326 obstack_1grow (&string_obstack, *cp);
2327 cp++;
2328 size++;
2331 while (cp < sp)
2333 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2335 /* Don't set a value if there are more than one
2336 instruction in the string. */
2337 obstack_blank_fast (&string_obstack, -size);
2338 size = 0;
2340 cp = sp;
2341 break;
2343 cp++;
2345 if (size == 0)
2346 obstack_1grow (&string_obstack, '*');
2347 else
2348 add_mnemonic_string (mnemonic_htab,
2349 (char *) obstack_next_free (&string_obstack) - size,
2350 size);
2351 i++;
2354 /* An insn definition might emit an empty string. */
2355 if (obstack_object_size (&string_obstack) == 0)
2356 return;
2358 obstack_1grow (&string_obstack, '\0');
2360 set_attr = rtx_alloc (SET_ATTR);
2361 XSTR (set_attr, 1) = XOBFINISH (&string_obstack, char *);
2362 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2363 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2364 XSTR (set_attr, 0) = attr_name;
2366 if (!XVEC (insn, 4))
2367 vec_len = 0;
2368 else
2369 vec_len = XVECLEN (insn, 4);
2371 new_vec = rtvec_alloc (vec_len + 1);
2372 for (i = 0; i < vec_len; i++)
2373 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2374 RTVEC_ELT (new_vec, vec_len) = set_attr;
2375 XVEC (insn, 4) = new_vec;
2378 /* This function is called for the elements in the mnemonic hashtable
2379 and generates a comma separated list of the mnemonics. */
2381 static int
2382 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2384 obstack_grow (&string_obstack, (char*)*slot, strlen ((char*)*slot));
2385 obstack_1grow (&string_obstack, ',');
2386 return 1;
2389 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2390 insn definition in case the back end requests it by defining the
2391 mnemonic attribute. The values for the attribute will be extracted
2392 from the output patterns of the insn definitions as far as
2393 possible. */
2395 static void
2396 gen_mnemonic_attr (void)
2398 struct queue_elem *elem;
2399 rtx mnemonic_attr = NULL;
2400 htab_t mnemonic_htab;
2401 const char *str, *p;
2402 int i;
2404 if (have_error)
2405 return;
2407 /* Look for the DEFINE_ATTR for `mnemonic'. */
2408 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2409 if (GET_CODE (elem->data) == DEFINE_ATTR
2410 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2412 mnemonic_attr = elem->data;
2413 break;
2416 /* A (define_attr "mnemonic" "...") indicates that the back-end
2417 wants a mnemonic attribute to be generated. */
2418 if (!mnemonic_attr)
2419 return;
2421 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2422 htab_eq_string, 0, xcalloc, free);
2424 for (elem = define_insn_queue; elem; elem = elem->next)
2426 rtx insn = elem->data;
2427 bool found = false;
2429 /* Check if the insn definition already has
2430 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2431 if (XVEC (insn, 4))
2432 for (i = 0; i < XVECLEN (insn, 4); i++)
2434 rtx set_attr = XVECEXP (insn, 4, i);
2436 switch (GET_CODE (set_attr))
2438 case SET_ATTR:
2439 case SET_ATTR_ALTERNATIVE:
2440 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
2441 found = true;
2442 break;
2443 case SET:
2444 if (GET_CODE (SET_DEST (set_attr)) == ATTR
2445 && strcmp (XSTR (SET_DEST (set_attr), 0),
2446 MNEMONIC_ATTR_NAME) == 0)
2447 found = true;
2448 break;
2449 default:
2450 break;
2454 if (!found)
2455 gen_mnemonic_setattr (mnemonic_htab, insn);
2458 /* Add the user defined values to the hash table. */
2459 str = XSTR (mnemonic_attr, 1);
2460 while ((p = scan_comma_elt (&str)) != NULL)
2461 add_mnemonic_string (mnemonic_htab, p, str - p);
2463 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2465 /* Replace the last ',' with the zero end character. */
2466 *((char *)obstack_next_free (&string_obstack) - 1) = '\0';
2467 XSTR (mnemonic_attr, 1) = XOBFINISH (&string_obstack, char *);
2470 /* Check if there are DEFINE_ATTRs with the same name. */
2471 static void
2472 check_define_attr_duplicates ()
2474 struct queue_elem *elem;
2475 htab_t attr_htab;
2476 char * attr_name;
2477 void **slot;
2479 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2481 for (elem = define_attr_queue; elem; elem = elem->next)
2483 attr_name = xstrdup (XSTR (elem->data, 0));
2485 slot = htab_find_slot (attr_htab, attr_name, INSERT);
2487 /* Duplicate. */
2488 if (*slot)
2490 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
2491 htab_delete (attr_htab);
2492 return;
2495 *slot = attr_name;
2498 htab_delete (attr_htab);
2501 /* The entry point for initializing the reader. */
2503 bool
2504 init_rtx_reader_args_cb (int argc, const char **argv,
2505 bool (*parse_opt) (const char *))
2507 /* Prepare to read input. */
2508 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2509 init_predicate_table ();
2510 obstack_init (rtl_obstack);
2512 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2513 insn_sequence_num = 1;
2515 /* These sequences are not used as indices, so can start at 1 also. */
2516 split_sequence_num = 1;
2517 peephole2_sequence_num = 1;
2519 read_md_files (argc, argv, parse_opt, rtx_handle_directive);
2521 if (define_attr_queue != NULL)
2522 check_define_attr_duplicates ();
2524 /* Process define_cond_exec patterns. */
2525 if (define_cond_exec_queue != NULL)
2526 process_define_cond_exec ();
2528 /* Process define_subst patterns. */
2529 if (define_subst_queue != NULL)
2530 process_define_subst ();
2532 if (define_attr_queue != NULL)
2533 gen_mnemonic_attr ();
2535 return !have_error;
2538 /* Programs that don't have their own options can use this entry point
2539 instead. */
2540 bool
2541 init_rtx_reader_args (int argc, const char **argv)
2543 return init_rtx_reader_args_cb (argc, argv, 0);
2546 /* Try to read a single rtx from the file. Return true on success,
2547 describing it in *INFO. */
2549 bool
2550 read_md_rtx (md_rtx_info *info)
2552 int truth, *counter;
2553 rtx def;
2555 /* Discard insn patterns which we know can never match (because
2556 their C test is provably always false). If insn_elision is
2557 false, our caller needs to see all the patterns. Note that the
2558 elided patterns are never counted by the sequence numbering; it
2559 is the caller's responsibility, when insn_elision is false, not
2560 to use elided pattern numbers for anything. */
2563 struct queue_elem **queue, *elem;
2565 /* Read all patterns from a given queue before moving on to the next. */
2566 if (define_attr_queue != NULL)
2567 queue = &define_attr_queue;
2568 else if (define_pred_queue != NULL)
2569 queue = &define_pred_queue;
2570 else if (define_insn_queue != NULL)
2571 queue = &define_insn_queue;
2572 else if (other_queue != NULL)
2573 queue = &other_queue;
2574 else
2575 return false;
2577 elem = *queue;
2578 *queue = elem->next;
2579 def = elem->data;
2580 info->def = def;
2581 info->loc = elem->loc;
2582 free (elem);
2584 truth = maybe_eval_c_test (get_c_test (def));
2586 while (truth == 0 && insn_elision);
2588 /* Perform code-specific processing and pick the appropriate sequence
2589 number counter. */
2590 switch (GET_CODE (def))
2592 case DEFINE_INSN:
2593 case DEFINE_EXPAND:
2594 /* insn_sequence_num is used here so the name table will match caller's
2595 idea of insn numbering, whether or not elision is active. */
2596 record_insn_name (insn_sequence_num, XSTR (def, 0));
2598 /* Fall through. */
2599 case DEFINE_PEEPHOLE:
2600 counter = &insn_sequence_num;
2601 break;
2603 case DEFINE_SPLIT:
2604 counter = &split_sequence_num;
2605 break;
2607 case DEFINE_PEEPHOLE2:
2608 counter = &peephole2_sequence_num;
2609 break;
2611 default:
2612 counter = NULL;
2613 break;
2616 if (counter)
2618 info->index = *counter;
2619 if (truth != 0)
2620 *counter += 1;
2622 else
2623 info->index = -1;
2625 if (!rtx_locs)
2626 rtx_locs = new hash_map <rtx, file_location>;
2627 rtx_locs->put (info->def, info->loc);
2629 return true;
2632 /* Return the file location of DEFINE_* rtx X, which was previously
2633 returned by read_md_rtx. */
2634 file_location
2635 get_file_location (rtx x)
2637 gcc_assert (rtx_locs);
2638 file_location *entry = rtx_locs->get (x);
2639 gcc_assert (entry);
2640 return *entry;
2643 /* Return the number of possible INSN_CODEs. Only meaningful once the
2644 whole file has been processed. */
2645 unsigned int
2646 get_num_insn_codes ()
2648 return insn_sequence_num;
2651 /* Return the C test that says whether definition rtx DEF can be used,
2652 or "" if it can be used unconditionally. */
2654 const char *
2655 get_c_test (rtx x)
2657 switch (GET_CODE (x))
2659 case DEFINE_INSN:
2660 case DEFINE_EXPAND:
2661 case DEFINE_SUBST:
2662 return XSTR (x, 2);
2664 case DEFINE_SPLIT:
2665 case DEFINE_PEEPHOLE:
2666 case DEFINE_PEEPHOLE2:
2667 return XSTR (x, 1);
2669 default:
2670 return "";
2674 /* Helper functions for insn elision. */
2676 /* Compute a hash function of a c_test structure, which is keyed
2677 by its ->expr field. */
2678 hashval_t
2679 hash_c_test (const void *x)
2681 const struct c_test *a = (const struct c_test *) x;
2682 const unsigned char *base, *s = (const unsigned char *) a->expr;
2683 hashval_t hash;
2684 unsigned char c;
2685 unsigned int len;
2687 base = s;
2688 hash = 0;
2690 while ((c = *s++) != '\0')
2692 hash += c + (c << 17);
2693 hash ^= hash >> 2;
2696 len = s - base;
2697 hash += len + (len << 17);
2698 hash ^= hash >> 2;
2700 return hash;
2703 /* Compare two c_test expression structures. */
2705 cmp_c_test (const void *x, const void *y)
2707 const struct c_test *a = (const struct c_test *) x;
2708 const struct c_test *b = (const struct c_test *) y;
2710 return !strcmp (a->expr, b->expr);
2713 /* Given a string representing a C test expression, look it up in the
2714 condition_table and report whether or not its value is known
2715 at compile time. Returns a tristate: 1 for known true, 0 for
2716 known false, -1 for unknown. */
2718 maybe_eval_c_test (const char *expr)
2720 const struct c_test *test;
2721 struct c_test dummy;
2723 if (expr[0] == 0)
2724 return 1;
2726 dummy.expr = expr;
2727 test = (const struct c_test *)htab_find (condition_table, &dummy);
2728 if (!test)
2729 return -1;
2730 return test->value;
2733 /* Record the C test expression EXPR in the condition_table, with
2734 value VAL. Duplicates clobber previous entries. */
2736 void
2737 add_c_test (const char *expr, int value)
2739 struct c_test *test;
2741 if (expr[0] == 0)
2742 return;
2744 test = XNEW (struct c_test);
2745 test->expr = expr;
2746 test->value = value;
2748 *(htab_find_slot (condition_table, test, INSERT)) = test;
2751 /* For every C test, call CALLBACK with two arguments: a pointer to
2752 the condition structure and INFO. Stops when CALLBACK returns zero. */
2753 void
2754 traverse_c_tests (htab_trav callback, void *info)
2756 if (condition_table)
2757 htab_traverse (condition_table, callback, info);
2760 /* Helper functions for define_predicate and define_special_predicate
2761 processing. Shared between genrecog.c and genpreds.c. */
2763 static htab_t predicate_table;
2764 struct pred_data *first_predicate;
2765 static struct pred_data **last_predicate = &first_predicate;
2767 static hashval_t
2768 hash_struct_pred_data (const void *ptr)
2770 return htab_hash_string (((const struct pred_data *)ptr)->name);
2773 static int
2774 eq_struct_pred_data (const void *a, const void *b)
2776 return !strcmp (((const struct pred_data *)a)->name,
2777 ((const struct pred_data *)b)->name);
2780 struct pred_data *
2781 lookup_predicate (const char *name)
2783 struct pred_data key;
2784 key.name = name;
2785 return (struct pred_data *) htab_find (predicate_table, &key);
2788 /* Record that predicate PRED can accept CODE. */
2790 void
2791 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2793 if (!pred->codes[code])
2795 pred->num_codes++;
2796 pred->codes[code] = true;
2798 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2799 pred->allows_non_const = true;
2801 if (code != REG
2802 && code != SUBREG
2803 && code != MEM
2804 && code != CONCAT
2805 && code != PARALLEL
2806 && code != STRICT_LOW_PART
2807 && code != SCRATCH)
2808 pred->allows_non_lvalue = true;
2810 if (pred->num_codes == 1)
2811 pred->singleton = code;
2812 else if (pred->num_codes == 2)
2813 pred->singleton = UNKNOWN;
2817 void
2818 add_predicate (struct pred_data *pred)
2820 void **slot = htab_find_slot (predicate_table, pred, INSERT);
2821 if (*slot)
2823 error ("duplicate predicate definition for '%s'", pred->name);
2824 return;
2826 *slot = pred;
2827 *last_predicate = pred;
2828 last_predicate = &pred->next;
2831 /* This array gives the initial content of the predicate table. It
2832 has entries for all predicates defined in recog.c. */
2834 struct std_pred_table
2836 const char *name;
2837 bool special;
2838 bool allows_const_p;
2839 RTX_CODE codes[NUM_RTX_CODE];
2842 static const struct std_pred_table std_preds[] = {
2843 {"general_operand", false, true, {SUBREG, REG, MEM}},
2844 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
2845 ZERO_EXTEND, SIGN_EXTEND, AND}},
2846 {"register_operand", false, false, {SUBREG, REG}},
2847 {"pmode_register_operand", true, false, {SUBREG, REG}},
2848 {"scratch_operand", false, false, {SCRATCH, REG}},
2849 {"immediate_operand", false, true, {UNKNOWN}},
2850 {"const_int_operand", false, false, {CONST_INT}},
2851 #if TARGET_SUPPORTS_WIDE_INT
2852 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
2853 {"const_double_operand", false, false, {CONST_DOUBLE}},
2854 #else
2855 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2856 #endif
2857 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2858 {"nonmemory_operand", false, true, {SUBREG, REG}},
2859 {"push_operand", false, false, {MEM}},
2860 {"pop_operand", false, false, {MEM}},
2861 {"memory_operand", false, false, {SUBREG, MEM}},
2862 {"indirect_operand", false, false, {SUBREG, MEM}},
2863 {"ordered_comparison_operator", false, false, {EQ, NE,
2864 LE, LT, GE, GT,
2865 LEU, LTU, GEU, GTU}},
2866 {"comparison_operator", false, false, {EQ, NE,
2867 LE, LT, GE, GT,
2868 LEU, LTU, GEU, GTU,
2869 UNORDERED, ORDERED,
2870 UNEQ, UNGE, UNGT,
2871 UNLE, UNLT, LTGT}}
2873 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2875 /* Initialize the table of predicate definitions, starting with
2876 the information we have on generic predicates. */
2878 static void
2879 init_predicate_table (void)
2881 size_t i, j;
2882 struct pred_data *pred;
2884 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2885 eq_struct_pred_data, 0,
2886 xcalloc, free);
2888 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2890 pred = XCNEW (struct pred_data);
2891 pred->name = std_preds[i].name;
2892 pred->special = std_preds[i].special;
2894 for (j = 0; std_preds[i].codes[j] != 0; j++)
2895 add_predicate_code (pred, std_preds[i].codes[j]);
2897 if (std_preds[i].allows_const_p)
2898 for (j = 0; j < NUM_RTX_CODE; j++)
2899 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2900 add_predicate_code (pred, (enum rtx_code) j);
2902 add_predicate (pred);
2906 /* These functions allow linkage with print-rtl.c. Also, some generators
2907 like to annotate their output with insn names. */
2909 /* Holds an array of names indexed by insn_code_number. */
2910 static char **insn_name_ptr = 0;
2911 static int insn_name_ptr_size = 0;
2913 const char *
2914 get_insn_name (int code)
2916 if (code < insn_name_ptr_size)
2917 return insn_name_ptr[code];
2918 else
2919 return NULL;
2922 static void
2923 record_insn_name (int code, const char *name)
2925 static const char *last_real_name = "insn";
2926 static int last_real_code = 0;
2927 char *new_name;
2929 if (insn_name_ptr_size <= code)
2931 int new_size;
2932 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
2933 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
2934 memset (insn_name_ptr + insn_name_ptr_size, 0,
2935 sizeof (char *) * (new_size - insn_name_ptr_size));
2936 insn_name_ptr_size = new_size;
2939 if (!name || name[0] == '\0')
2941 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
2942 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
2944 else
2946 last_real_name = new_name = xstrdup (name);
2947 last_real_code = code;
2950 insn_name_ptr[code] = new_name;
2953 /* Make STATS describe the operands that appear in rtx X. */
2955 static void
2956 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
2958 RTX_CODE code;
2959 int i;
2960 int len;
2961 const char *fmt;
2963 if (x == NULL_RTX)
2964 return;
2966 code = GET_CODE (x);
2967 switch (code)
2969 case MATCH_OPERAND:
2970 case MATCH_OPERATOR:
2971 case MATCH_PARALLEL:
2972 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
2973 break;
2975 case MATCH_DUP:
2976 case MATCH_OP_DUP:
2977 case MATCH_PAR_DUP:
2978 stats->num_dups++;
2979 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
2980 break;
2982 case MATCH_SCRATCH:
2983 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
2984 break;
2986 default:
2987 break;
2990 fmt = GET_RTX_FORMAT (code);
2991 len = GET_RTX_LENGTH (code);
2992 for (i = 0; i < len; i++)
2994 if (fmt[i] == 'e' || fmt[i] == 'u')
2995 get_pattern_stats_1 (stats, XEXP (x, i));
2996 else if (fmt[i] == 'E')
2998 int j;
2999 for (j = 0; j < XVECLEN (x, i); j++)
3000 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3005 /* Make STATS describe the operands that appear in instruction pattern
3006 PATTERN. */
3008 void
3009 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3011 int i, len;
3013 stats->max_opno = -1;
3014 stats->max_dup_opno = -1;
3015 stats->max_scratch_opno = -1;
3016 stats->num_dups = 0;
3018 len = GET_NUM_ELEM (pattern);
3019 for (i = 0; i < len; i++)
3020 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3022 stats->num_generator_args = stats->max_opno + 1;
3023 stats->num_insn_operands = MAX (stats->max_opno,
3024 stats->max_scratch_opno) + 1;
3025 stats->num_operand_vars = MAX (stats->max_opno,
3026 MAX (stats->max_dup_opno,
3027 stats->max_scratch_opno)) + 1;
3030 /* Return the emit_* function that should be used for pattern X, or NULL
3031 if we can't pick a particular type at compile time and should instead
3032 fall back to "emit". */
3034 const char *
3035 get_emit_function (rtx x)
3037 switch (classify_insn (x))
3039 case INSN:
3040 return "emit_insn";
3042 case CALL_INSN:
3043 return "emit_call_insn";
3045 case JUMP_INSN:
3046 return "emit_jump_insn";
3048 case UNKNOWN:
3049 return NULL;
3051 default:
3052 gcc_unreachable ();
3056 /* Return true if we must emit a barrier after pattern X. */
3058 bool
3059 needs_barrier_p (rtx x)
3061 return (GET_CODE (x) == SET
3062 && GET_CODE (SET_DEST (x)) == PC
3063 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3066 #define NS "NULL"
3067 #define ZS "'\\0'"
3068 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3069 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3070 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3071 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3072 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3073 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3074 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3075 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3076 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3077 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3078 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3080 /* An array of all optabs. Note that the same optab can appear more
3081 than once, with a different pattern. */
3082 optab_def optabs[] = {
3083 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3084 #include "optabs.def"
3087 /* The number of entries in optabs[]. */
3088 unsigned int num_optabs = ARRAY_SIZE (optabs);
3090 #undef OPTAB_CL
3091 #undef OPTAB_CX
3092 #undef OPTAB_CD
3093 #undef OPTAB_NL
3094 #undef OPTAB_NC
3095 #undef OPTAB_NX
3096 #undef OPTAB_VL
3097 #undef OPTAB_VC
3098 #undef OPTAB_VX
3099 #undef OPTAB_DC
3100 #undef OPTAB_D
3102 /* Return true if instruction NAME matches pattern PAT, storing information
3103 about the match in P if so. */
3105 static bool
3106 match_pattern (optab_pattern *p, const char *name, const char *pat)
3108 bool force_float = false;
3109 bool force_int = false;
3110 bool force_partial_int = false;
3111 bool force_fixed = false;
3113 if (pat == NULL)
3114 return false;
3115 for (; ; ++pat)
3117 if (*pat != '$')
3119 if (*pat != *name++)
3120 return false;
3121 if (*pat == '\0')
3122 return true;
3123 continue;
3125 switch (*++pat)
3127 case 'I':
3128 force_int = 1;
3129 break;
3130 case 'P':
3131 force_partial_int = 1;
3132 break;
3133 case 'F':
3134 force_float = 1;
3135 break;
3136 case 'Q':
3137 force_fixed = 1;
3138 break;
3140 case 'a':
3141 case 'b':
3143 int i;
3145 /* This loop will stop at the first prefix match, so
3146 look through the modes in reverse order, in case
3147 there are extra CC modes and CC is a prefix of the
3148 CC modes (as it should be). */
3149 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3151 const char *p, *q;
3152 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3153 if (TOLOWER (*p) != *q)
3154 break;
3155 if (*p == 0
3156 && (! force_int || mode_class[i] == MODE_INT
3157 || mode_class[i] == MODE_VECTOR_INT)
3158 && (! force_partial_int
3159 || mode_class[i] == MODE_INT
3160 || mode_class[i] == MODE_PARTIAL_INT
3161 || mode_class[i] == MODE_VECTOR_INT)
3162 && (! force_float
3163 || mode_class[i] == MODE_FLOAT
3164 || mode_class[i] == MODE_DECIMAL_FLOAT
3165 || mode_class[i] == MODE_COMPLEX_FLOAT
3166 || mode_class[i] == MODE_VECTOR_FLOAT)
3167 && (! force_fixed
3168 || mode_class[i] == MODE_FRACT
3169 || mode_class[i] == MODE_UFRACT
3170 || mode_class[i] == MODE_ACCUM
3171 || mode_class[i] == MODE_UACCUM
3172 || mode_class[i] == MODE_VECTOR_FRACT
3173 || mode_class[i] == MODE_VECTOR_UFRACT
3174 || mode_class[i] == MODE_VECTOR_ACCUM
3175 || mode_class[i] == MODE_VECTOR_UACCUM))
3176 break;
3179 if (i < 0)
3180 return false;
3181 name += strlen (GET_MODE_NAME (i));
3182 if (*pat == 'a')
3183 p->m1 = i;
3184 else
3185 p->m2 = i;
3187 force_int = false;
3188 force_partial_int = false;
3189 force_float = false;
3190 force_fixed = false;
3192 break;
3194 default:
3195 gcc_unreachable ();
3200 /* Return true if NAME is the name of an optab, describing it in P if so. */
3202 bool
3203 find_optab (optab_pattern *p, const char *name)
3205 if (*name == 0 || *name == '*')
3206 return false;
3208 /* See if NAME matches one of the patterns we have for the optabs
3209 we know about. */
3210 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3212 p->m1 = p->m2 = 0;
3213 if (match_pattern (p, name, optabs[pindex].pattern))
3215 p->name = name;
3216 p->op = optabs[pindex].op;
3217 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
3218 return true;
3221 return false;