[gcc]
[official-gcc.git] / gcc / gensupport.c
blobc79feb48ad15d619cf4e8fde2a65995a42b4ddf4
1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2017 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, -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 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
555 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
556 split_cond + 2);
558 XSTR (split, 1) = split_cond;
559 XVEC (split, 2) = XVEC (desc, 5);
560 XSTR (split, 3) = XSTR (desc, 6);
562 /* Fix up the DEFINE_INSN. */
563 attr = XVEC (desc, 7);
564 PUT_CODE (desc, DEFINE_INSN);
565 XVEC (desc, 4) = attr;
567 /* Queue them. */
568 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
569 split_elem = queue_pattern (split, &other_tail, loc);
570 insn_elem->split = split_elem;
571 break;
574 default:
575 queue_pattern (desc, &other_tail, loc);
576 break;
580 /* Return true if attribute PREDICABLE is true for ELEM, which holds
581 a DEFINE_INSN. */
583 static int
584 is_predicable (struct queue_elem *elem)
586 rtvec vec = XVEC (elem->data, 4);
587 const char *value;
588 int i;
590 if (! vec)
591 return predicable_default;
593 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
595 rtx sub = RTVEC_ELT (vec, i);
596 switch (GET_CODE (sub))
598 case SET_ATTR:
599 if (strcmp (XSTR (sub, 0), "predicable") == 0)
601 value = XSTR (sub, 1);
602 goto found;
604 break;
606 case SET_ATTR_ALTERNATIVE:
607 if (strcmp (XSTR (sub, 0), "predicable") == 0)
609 error_at (elem->loc, "multiple alternatives for `predicable'");
610 return 0;
612 break;
614 case SET:
615 if (GET_CODE (SET_DEST (sub)) != ATTR
616 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
617 break;
618 sub = SET_SRC (sub);
619 if (GET_CODE (sub) == CONST_STRING)
621 value = XSTR (sub, 0);
622 goto found;
625 /* ??? It would be possible to handle this if we really tried.
626 It's not easy though, and I'm not going to bother until it
627 really proves necessary. */
628 error_at (elem->loc, "non-constant value for `predicable'");
629 return 0;
631 default:
632 gcc_unreachable ();
636 return predicable_default;
638 found:
639 /* Find out which value we're looking at. Multiple alternatives means at
640 least one is predicable. */
641 if (strchr (value, ',') != NULL)
642 return 1;
643 if (strcmp (value, predicable_true) == 0)
644 return 1;
645 if (strcmp (value, predicable_false) == 0)
646 return 0;
648 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
649 return 0;
652 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
653 static void
654 change_subst_attribute (struct queue_elem *elem,
655 struct queue_elem *subst_elem,
656 const char *new_value)
658 rtvec attrs_vec = XVEC (elem->data, 4);
659 const char *subst_name = XSTR (subst_elem->data, 0);
660 int i;
662 if (! attrs_vec)
663 return;
665 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
667 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
668 if (GET_CODE (cur_attr) != SET_ATTR)
669 continue;
670 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
672 XSTR (cur_attr, 1) = new_value;
673 return;
678 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
679 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
680 DEFINE_SUBST isn't applied to patterns without such attribute. In other
681 words, we suppose the default value of the attribute to be 'no' since it is
682 always generated automatically in read-rtl.c. */
683 static bool
684 has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem)
686 rtvec attrs_vec = XVEC (elem->data, 4);
687 const char *value, *subst_name = XSTR (subst_elem->data, 0);
688 int i;
690 if (! attrs_vec)
691 return false;
693 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
695 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
696 switch (GET_CODE (cur_attr))
698 case SET_ATTR:
699 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
701 value = XSTR (cur_attr, 1);
702 goto found;
704 break;
706 case SET:
707 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
708 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
709 break;
710 cur_attr = SET_SRC (cur_attr);
711 if (GET_CODE (cur_attr) == CONST_STRING)
713 value = XSTR (cur_attr, 0);
714 goto found;
717 /* Only (set_attr "subst" "yes/no") and
718 (set (attr "subst" (const_string "yes/no")))
719 are currently allowed. */
720 error_at (elem->loc, "unsupported value for `%s'", subst_name);
721 return false;
723 case SET_ATTR_ALTERNATIVE:
724 error_at (elem->loc,
725 "%s: `set_attr_alternative' is unsupported by "
726 "`define_subst'", XSTR (elem->data, 0));
727 return false;
730 default:
731 gcc_unreachable ();
735 return false;
737 found:
738 if (strcmp (value, subst_true) == 0)
739 return true;
740 if (strcmp (value, subst_false) == 0)
741 return false;
743 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
744 value, subst_name);
745 return false;
748 /* Compare RTL-template of original define_insn X to input RTL-template of
749 define_subst PT. Return 1 if the templates match, 0 otherwise.
750 During the comparison, the routine also fills global_array OPERAND_DATA. */
751 static bool
752 subst_pattern_match (rtx x, rtx pt, file_location loc)
754 RTX_CODE code, code_pt;
755 int i, j, len;
756 const char *fmt, *pred_name;
758 code = GET_CODE (x);
759 code_pt = GET_CODE (pt);
761 if (code_pt == MATCH_OPERAND)
763 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
764 always accept them. */
765 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
766 && (code != MATCH_DUP && code != MATCH_OP_DUP))
767 return false; /* Modes don't match. */
769 if (code == MATCH_OPERAND)
771 pred_name = XSTR (pt, 1);
772 if (pred_name[0] != 0)
774 const struct pred_data *pred_pt = lookup_predicate (pred_name);
775 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
776 return false; /* Predicates don't match. */
780 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
781 operand_data[XINT (pt, 0)] = x;
782 return true;
785 if (code_pt == MATCH_OPERATOR)
787 int x_vecexp_pos = -1;
789 /* Compare modes. */
790 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
791 return false;
793 /* In case X is also match_operator, compare predicates. */
794 if (code == MATCH_OPERATOR)
796 pred_name = XSTR (pt, 1);
797 if (pred_name[0] != 0)
799 const struct pred_data *pred_pt = lookup_predicate (pred_name);
800 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
801 return false;
805 /* Compare operands.
806 MATCH_OPERATOR in input template could match in original template
807 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
808 In the first case operands are at (XVECEXP (x, 2, j)), in the second
809 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
810 X_VECEXP_POS variable shows, where to look for these operands. */
811 if (code == UNSPEC
812 || code == UNSPEC_VOLATILE)
813 x_vecexp_pos = 0;
814 else if (code == MATCH_OPERATOR)
815 x_vecexp_pos = 2;
816 else
817 x_vecexp_pos = -1;
819 /* MATCH_OPERATOR or UNSPEC case. */
820 if (x_vecexp_pos >= 0)
822 /* Compare operands number in X and PT. */
823 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
824 return false;
825 for (j = 0; j < XVECLEN (pt, 2); j++)
826 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
827 XVECEXP (pt, 2, j), loc))
828 return false;
831 /* Ordinary operator. */
832 else
834 /* Compare operands number in X and PT.
835 We count operands differently for X and PT since we compare
836 an operator (with operands directly in RTX) and MATCH_OPERATOR
837 (that has a vector with operands). */
838 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
839 return false;
840 for (j = 0; j < XVECLEN (pt, 2); j++)
841 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
842 return false;
845 /* Store the operand to OPERAND_DATA array. */
846 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
847 operand_data[XINT (pt, 0)] = x;
848 return true;
851 if (code_pt == MATCH_PAR_DUP
852 || code_pt == MATCH_DUP
853 || code_pt == MATCH_OP_DUP
854 || code_pt == MATCH_SCRATCH
855 || code_pt == MATCH_PARALLEL)
857 /* Currently interface for these constructions isn't defined -
858 probably they aren't needed in input template of define_subst at all.
859 So, for now their usage in define_subst is forbidden. */
860 error_at (loc, "%s cannot be used in define_subst",
861 GET_RTX_NAME (code_pt));
864 gcc_assert (code != MATCH_PAR_DUP
865 && code_pt != MATCH_DUP
866 && code_pt != MATCH_OP_DUP
867 && code_pt != MATCH_SCRATCH
868 && code_pt != MATCH_PARALLEL
869 && code_pt != MATCH_OPERAND
870 && code_pt != MATCH_OPERATOR);
871 /* If PT is none of the handled above, then we match only expressions with
872 the same code in X. */
873 if (code != code_pt)
874 return false;
876 fmt = GET_RTX_FORMAT (code_pt);
877 len = GET_RTX_LENGTH (code_pt);
879 for (i = 0; i < len; i++)
881 if (fmt[i] == '0')
882 break;
884 switch (fmt[i])
886 case 'i': case 'r': case 'w': case 's':
887 continue;
889 case 'e': case 'u':
890 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
891 return false;
892 break;
893 case 'E':
895 if (XVECLEN (x, i) != XVECLEN (pt, i))
896 return false;
897 for (j = 0; j < XVECLEN (pt, i); j++)
898 if (!subst_pattern_match (XVECEXP (x, i, j),
899 XVECEXP (pt, i, j), loc))
900 return false;
901 break;
903 default:
904 gcc_unreachable ();
908 return true;
911 /* Examine the attribute "predicable"; discover its boolean values
912 and its default. */
914 static void
915 identify_predicable_attribute (void)
917 struct queue_elem *elem;
918 char *p_true, *p_false;
919 const char *value;
921 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
922 for (elem = define_attr_queue; elem ; elem = elem->next)
923 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
924 goto found;
926 error_at (define_cond_exec_queue->loc,
927 "attribute `predicable' not defined");
928 return;
930 found:
931 value = XSTR (elem->data, 1);
932 p_false = xstrdup (value);
933 p_true = strchr (p_false, ',');
934 if (p_true == NULL || strchr (++p_true, ',') != NULL)
936 error_at (elem->loc, "attribute `predicable' is not a boolean");
937 free (p_false);
938 return;
940 p_true[-1] = '\0';
942 predicable_true = p_true;
943 predicable_false = p_false;
945 switch (GET_CODE (XEXP (elem->data, 2)))
947 case CONST_STRING:
948 value = XSTR (XEXP (elem->data, 2), 0);
949 break;
951 case CONST:
952 error_at (elem->loc, "attribute `predicable' cannot be const");
953 free (p_false);
954 return;
956 default:
957 error_at (elem->loc,
958 "attribute `predicable' must have a constant default");
959 free (p_false);
960 return;
963 if (strcmp (value, p_true) == 0)
964 predicable_default = 1;
965 else if (strcmp (value, p_false) == 0)
966 predicable_default = 0;
967 else
969 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
970 value);
971 free (p_false);
975 /* Return the number of alternatives in constraint S. */
977 static int
978 n_alternatives (const char *s)
980 int n = 1;
982 if (s)
983 while (*s)
984 n += (*s++ == ',');
986 return n;
989 /* The routine scans rtl PATTERN, find match_operand in it and counts
990 number of alternatives. If PATTERN contains several match_operands
991 with different number of alternatives, error is emitted, and the
992 routine returns 0. If all match_operands in PATTERN have the same
993 number of alternatives, it's stored in N_ALT, and the routine returns 1.
994 LOC is the location of PATTERN, for error reporting. */
995 static int
996 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
998 const char *fmt;
999 enum rtx_code code;
1000 int i, j, len;
1002 if (!n_alt)
1003 return 0;
1005 code = GET_CODE (pattern);
1006 switch (code)
1008 case MATCH_OPERAND:
1009 i = n_alternatives (XSTR (pattern, 2));
1010 /* n_alternatives returns 1 if constraint string is empty -
1011 here we fix it up. */
1012 if (!*(XSTR (pattern, 2)))
1013 i = 0;
1014 if (*n_alt <= 0)
1015 *n_alt = i;
1017 else if (i && i != *n_alt)
1019 error_at (loc, "wrong number of alternatives in operand %d",
1020 XINT (pattern, 0));
1021 return 0;
1024 default:
1025 break;
1028 fmt = GET_RTX_FORMAT (code);
1029 len = GET_RTX_LENGTH (code);
1030 for (i = 0; i < len; i++)
1032 switch (fmt[i])
1034 case 'e': case 'u':
1035 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1036 return 0;
1037 break;
1039 case 'V':
1040 if (XVEC (pattern, i) == NULL)
1041 break;
1042 /* FALLTHRU */
1044 case 'E':
1045 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1046 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1047 return 0;
1048 break;
1050 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1051 break;
1053 default:
1054 gcc_unreachable ();
1057 return 1;
1060 /* Determine how many alternatives there are in INSN, and how many
1061 operands. */
1063 static void
1064 collect_insn_data (rtx pattern, int *palt, int *pmax)
1066 const char *fmt;
1067 enum rtx_code code;
1068 int i, j, len;
1070 code = GET_CODE (pattern);
1071 switch (code)
1073 case MATCH_OPERAND:
1074 case MATCH_SCRATCH:
1075 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1076 *palt = (i > *palt ? i : *palt);
1077 /* Fall through. */
1079 case MATCH_OPERATOR:
1080 case MATCH_PARALLEL:
1081 i = XINT (pattern, 0);
1082 if (i > *pmax)
1083 *pmax = i;
1084 break;
1086 default:
1087 break;
1090 fmt = GET_RTX_FORMAT (code);
1091 len = GET_RTX_LENGTH (code);
1092 for (i = 0; i < len; i++)
1094 switch (fmt[i])
1096 case 'e': case 'u':
1097 collect_insn_data (XEXP (pattern, i), palt, pmax);
1098 break;
1100 case 'V':
1101 if (XVEC (pattern, i) == NULL)
1102 break;
1103 /* Fall through. */
1104 case 'E':
1105 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1106 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1107 break;
1109 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1110 break;
1112 default:
1113 gcc_unreachable ();
1118 static rtx
1119 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1120 file_location loc)
1122 const char *fmt;
1123 enum rtx_code code;
1124 int i, j, len;
1126 code = GET_CODE (pattern);
1127 switch (code)
1129 case MATCH_OPERAND:
1131 const char *c = XSTR (pattern, 2);
1133 if (n_alternatives (c) != 1)
1135 error_at (loc, "too many alternatives for operand %d",
1136 XINT (pattern, 0));
1137 return NULL;
1140 /* Replicate C as needed to fill out ALT alternatives. */
1141 if (c && *c && alt > 1)
1143 size_t c_len = strlen (c);
1144 size_t len = alt * (c_len + 1);
1145 char *new_c = XNEWVEC (char, len);
1147 memcpy (new_c, c, c_len);
1148 for (i = 1; i < alt; ++i)
1150 new_c[i * (c_len + 1) - 1] = ',';
1151 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1153 new_c[len - 1] = '\0';
1154 XSTR (pattern, 2) = new_c;
1157 /* Fall through. */
1159 case MATCH_OPERATOR:
1160 case MATCH_SCRATCH:
1161 case MATCH_PARALLEL:
1162 XINT (pattern, 0) += max_op;
1163 break;
1165 default:
1166 break;
1169 fmt = GET_RTX_FORMAT (code);
1170 len = GET_RTX_LENGTH (code);
1171 for (i = 0; i < len; i++)
1173 rtx r;
1175 switch (fmt[i])
1177 case 'e': case 'u':
1178 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1179 if (r == NULL)
1180 return r;
1181 break;
1183 case 'E':
1184 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1186 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1187 alt, max_op, loc);
1188 if (r == NULL)
1189 return r;
1191 break;
1193 case 'i': case 'r': case 'w': case '0': case 's':
1194 break;
1196 default:
1197 gcc_unreachable ();
1201 return pattern;
1204 /* Duplicate constraints in PATTERN. If pattern is from original
1205 rtl-template, we need to duplicate each alternative - for that we
1206 need to use duplicate_each_alternative () as a functor ALTER.
1207 If pattern is from output-pattern of define_subst, we need to
1208 duplicate constraints in another way - with duplicate_alternatives ().
1209 N_DUP is multiplication factor. */
1210 static rtx
1211 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1213 const char *fmt;
1214 enum rtx_code code;
1215 int i, j, len;
1217 code = GET_CODE (pattern);
1218 switch (code)
1220 case MATCH_OPERAND:
1221 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1222 break;
1224 default:
1225 break;
1228 fmt = GET_RTX_FORMAT (code);
1229 len = GET_RTX_LENGTH (code);
1230 for (i = 0; i < len; i++)
1232 rtx r;
1234 switch (fmt[i])
1236 case 'e': case 'u':
1237 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1238 if (r == NULL)
1239 return r;
1240 break;
1242 case 'E':
1243 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1245 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1246 if (r == NULL)
1247 return r;
1249 break;
1251 case 'i': case 'r': case 'w': case '0': case 's':
1252 break;
1254 default:
1255 break;
1259 return pattern;
1262 static const char *
1263 alter_test_for_insn (struct queue_elem *ce_elem,
1264 struct queue_elem *insn_elem)
1266 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
1267 XSTR (insn_elem->data, 2));
1270 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1271 to take "ce_enabled" into account. Return the new expression. */
1272 static rtx
1273 modify_attr_enabled_ce (rtx val)
1275 rtx eq_attr, str;
1276 rtx ite;
1277 eq_attr = rtx_alloc (EQ_ATTR);
1278 ite = rtx_alloc (IF_THEN_ELSE);
1279 str = rtx_alloc (CONST_STRING);
1281 XSTR (eq_attr, 0) = "ce_enabled";
1282 XSTR (eq_attr, 1) = "yes";
1283 XSTR (str, 0) = "no";
1284 XEXP (ite, 0) = eq_attr;
1285 XEXP (ite, 1) = val;
1286 XEXP (ite, 2) = str;
1288 return ite;
1291 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1292 from a define_insn pattern. We must modify the "predicable" attribute
1293 to be named "ce_enabled", and also change any "enabled" attribute that's
1294 present so that it takes ce_enabled into account.
1295 We rely on the fact that INSN was created with copy_rtx, and modify data
1296 in-place. */
1298 static void
1299 alter_attrs_for_insn (rtx insn)
1301 static bool global_changes_made = false;
1302 rtvec vec = XVEC (insn, 4);
1303 rtvec new_vec;
1304 rtx val, set;
1305 int num_elem;
1306 int predicable_idx = -1;
1307 int enabled_idx = -1;
1308 int i;
1310 if (! vec)
1311 return;
1313 num_elem = GET_NUM_ELEM (vec);
1314 for (i = num_elem - 1; i >= 0; --i)
1316 rtx sub = RTVEC_ELT (vec, i);
1317 switch (GET_CODE (sub))
1319 case SET_ATTR:
1320 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1322 predicable_idx = i;
1323 XSTR (sub, 0) = "ce_enabled";
1325 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1327 enabled_idx = i;
1328 XSTR (sub, 0) = "nonce_enabled";
1330 break;
1332 case SET_ATTR_ALTERNATIVE:
1333 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1334 /* We already give an error elsewhere. */
1335 return;
1336 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1338 enabled_idx = i;
1339 XSTR (sub, 0) = "nonce_enabled";
1341 break;
1343 case SET:
1344 if (GET_CODE (SET_DEST (sub)) != ATTR)
1345 break;
1346 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1348 sub = SET_SRC (sub);
1349 if (GET_CODE (sub) == CONST_STRING)
1351 predicable_idx = i;
1352 XSTR (sub, 0) = "ce_enabled";
1354 else
1355 /* We already give an error elsewhere. */
1356 return;
1357 break;
1359 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1361 enabled_idx = i;
1362 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1364 break;
1366 default:
1367 gcc_unreachable ();
1370 if (predicable_idx == -1)
1371 return;
1373 if (!global_changes_made)
1375 struct queue_elem *elem;
1377 global_changes_made = true;
1378 add_define_attr ("ce_enabled");
1379 add_define_attr ("nonce_enabled");
1381 for (elem = define_attr_queue; elem ; elem = elem->next)
1382 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1384 XEXP (elem->data, 2)
1385 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1388 if (enabled_idx == -1)
1389 return;
1391 new_vec = rtvec_alloc (num_elem + 1);
1392 for (i = 0; i < num_elem; i++)
1393 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1394 val = rtx_alloc (IF_THEN_ELSE);
1395 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1396 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1397 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1398 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1399 XSTR (XEXP (val, 0), 1) = "yes";
1400 XSTR (XEXP (val, 1), 0) = "yes";
1401 XSTR (XEXP (val, 2), 0) = "no";
1402 set = rtx_alloc (SET);
1403 SET_DEST (set) = rtx_alloc (ATTR);
1404 XSTR (SET_DEST (set), 0) = "enabled";
1405 SET_SRC (set) = modify_attr_enabled_ce (val);
1406 RTVEC_ELT (new_vec, i) = set;
1407 XVEC (insn, 4) = new_vec;
1410 /* As number of constraints is changed after define_subst, we need to
1411 process attributes as well - we need to duplicate them the same way
1412 that we duplicated constraints in original pattern
1413 ELEM is a queue element, containing our rtl-template,
1414 N_DUP - multiplication factor. */
1415 static void
1416 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
1418 rtvec vec = XVEC (elem->data, 4);
1419 int num_elem;
1420 int i;
1422 if (n_dup < 2 || ! vec)
1423 return;
1425 num_elem = GET_NUM_ELEM (vec);
1426 for (i = num_elem - 1; i >= 0; --i)
1428 rtx sub = RTVEC_ELT (vec, i);
1429 switch (GET_CODE (sub))
1431 case SET_ATTR:
1432 if (strchr (XSTR (sub, 1), ',') != NULL)
1433 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1434 break;
1436 case SET_ATTR_ALTERNATIVE:
1437 case SET:
1438 error_at (elem->loc,
1439 "%s: `define_subst' does not support attributes "
1440 "assigned by `set' and `set_attr_alternative'",
1441 XSTR (elem->data, 0));
1442 return;
1444 default:
1445 gcc_unreachable ();
1450 /* Adjust all of the operand numbers in SRC to match the shift they'll
1451 get from an operand displacement of DISP. Return a pointer after the
1452 adjusted string. */
1454 static char *
1455 shift_output_template (char *dest, const char *src, int disp)
1457 while (*src)
1459 char c = *src++;
1460 *dest++ = c;
1461 if (c == '%')
1463 c = *src++;
1464 if (ISDIGIT ((unsigned char) c))
1465 c += disp;
1466 else if (ISALPHA (c))
1468 *dest++ = c;
1469 c = *src++ + disp;
1471 *dest++ = c;
1475 return dest;
1478 static const char *
1479 alter_output_for_insn (struct queue_elem *ce_elem,
1480 struct queue_elem *insn_elem,
1481 int alt, int max_op)
1483 const char *ce_out, *insn_out;
1484 char *result, *p;
1485 size_t len, ce_len, insn_len;
1487 /* ??? Could coordinate with genoutput to not duplicate code here. */
1489 ce_out = XSTR (ce_elem->data, 2);
1490 insn_out = XTMPL (insn_elem->data, 3);
1491 if (!ce_out || *ce_out == '\0')
1492 return insn_out;
1494 ce_len = strlen (ce_out);
1495 insn_len = strlen (insn_out);
1497 if (*insn_out == '*')
1498 /* You must take care of the predicate yourself. */
1499 return insn_out;
1501 if (*insn_out == '@')
1503 len = (ce_len + 1) * alt + insn_len + 1;
1504 p = result = XNEWVEC (char, len);
1509 *p++ = *insn_out++;
1510 while (ISSPACE ((unsigned char) *insn_out));
1512 if (*insn_out != '#')
1514 p = shift_output_template (p, ce_out, max_op);
1515 *p++ = ' ';
1519 *p++ = *insn_out++;
1520 while (*insn_out && *insn_out != '\n');
1522 while (*insn_out);
1523 *p = '\0';
1525 else
1527 len = ce_len + 1 + insn_len + 1;
1528 result = XNEWVEC (char, len);
1530 p = shift_output_template (result, ce_out, max_op);
1531 *p++ = ' ';
1532 memcpy (p, insn_out, insn_len + 1);
1535 return result;
1538 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1539 string, duplicated N_DUP times. */
1541 static const char *
1542 duplicate_alternatives (const char * str, int n_dup)
1544 int i, len, new_len;
1545 char *result, *sp;
1546 const char *cp;
1548 if (n_dup < 2)
1549 return str;
1551 while (ISSPACE (*str))
1552 str++;
1554 if (*str == '\0')
1555 return str;
1557 cp = str;
1558 len = strlen (str);
1559 new_len = (len + 1) * n_dup;
1561 sp = result = XNEWVEC (char, new_len);
1563 /* Global modifier characters mustn't be duplicated: skip if found. */
1564 if (*cp == '=' || *cp == '+' || *cp == '%')
1566 *sp++ = *cp++;
1567 len--;
1570 /* Copy original constraints N_DUP times. */
1571 for (i = 0; i < n_dup; i++, sp += len+1)
1573 memcpy (sp, cp, len);
1574 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1577 return result;
1580 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1581 each alternative from the original string is duplicated N_DUP times. */
1582 static const char *
1583 duplicate_each_alternative (const char * str, int n_dup)
1585 int i, len, new_len;
1586 char *result, *sp, *ep, *cp;
1588 if (n_dup < 2)
1589 return str;
1591 while (ISSPACE (*str))
1592 str++;
1594 if (*str == '\0')
1595 return str;
1597 cp = xstrdup (str);
1599 new_len = (strlen (cp) + 1) * n_dup;
1601 sp = result = XNEWVEC (char, new_len);
1603 /* Global modifier characters mustn't be duplicated: skip if found. */
1604 if (*cp == '=' || *cp == '+' || *cp == '%')
1605 *sp++ = *cp++;
1609 if ((ep = strchr (cp, ',')) != NULL)
1610 *ep++ = '\0';
1611 len = strlen (cp);
1613 /* Copy a constraint N_DUP times. */
1614 for (i = 0; i < n_dup; i++, sp += len + 1)
1616 memcpy (sp, cp, len);
1617 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1620 cp = ep;
1622 while (cp != NULL);
1624 return result;
1627 /* Alter the output of INSN whose pattern was modified by
1628 DEFINE_SUBST. We must replicate output strings according
1629 to the new number of alternatives ALT in substituted pattern.
1630 If ALT equals 1, output has one alternative or defined by C
1631 code, then output is returned without any changes. */
1633 static const char *
1634 alter_output_for_subst_insn (rtx insn, int alt)
1636 const char *insn_out, *old_out;
1637 char *new_out, *cp;
1638 size_t old_len, new_len;
1639 int j;
1641 insn_out = XTMPL (insn, 3);
1643 if (alt < 2 || *insn_out != '@')
1644 return insn_out;
1646 old_out = insn_out + 1;
1647 while (ISSPACE (*old_out))
1648 old_out++;
1649 old_len = strlen (old_out);
1651 new_len = alt * (old_len + 1) + 1;
1653 new_out = XNEWVEC (char, new_len);
1654 new_out[0] = '@';
1656 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
1658 memcpy (cp, old_out, old_len);
1659 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
1662 return new_out;
1665 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1667 static void
1668 process_one_cond_exec (struct queue_elem *ce_elem)
1670 struct queue_elem *insn_elem;
1671 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1673 int alternatives, max_operand;
1674 rtx pred, insn, pattern, split;
1675 char *new_name;
1676 int i;
1678 if (! is_predicable (insn_elem))
1679 continue;
1681 alternatives = 1;
1682 max_operand = -1;
1683 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1684 max_operand += 1;
1686 if (XVECLEN (ce_elem->data, 0) != 1)
1688 error_at (ce_elem->loc, "too many patterns in predicate");
1689 return;
1692 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1693 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1694 ce_elem->loc);
1695 if (pred == NULL)
1696 return;
1698 /* Construct a new pattern for the new insn. */
1699 insn = copy_rtx (insn_elem->data);
1700 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1701 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1702 XSTR (insn, 0) = new_name;
1703 pattern = rtx_alloc (COND_EXEC);
1704 XEXP (pattern, 0) = pred;
1705 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
1706 XVEC (insn, 1) = rtvec_alloc (1);
1707 XVECEXP (insn, 1, 0) = pattern;
1709 if (XVEC (ce_elem->data, 3) != NULL)
1711 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
1712 + XVECLEN (ce_elem->data, 3));
1713 int i = 0;
1714 int j = 0;
1715 for (i = 0; i < XVECLEN (insn, 4); i++)
1716 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
1718 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
1719 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
1721 XVEC (insn, 4) = attributes;
1724 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1725 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1726 alternatives, max_operand);
1727 alter_attrs_for_insn (insn);
1729 /* Put the new pattern on the `other' list so that it
1730 (a) is not reprocessed by other define_cond_exec patterns
1731 (b) appears after all normal define_insn patterns.
1733 ??? B is debatable. If one has normal insns that match
1734 cond_exec patterns, they will be preferred over these
1735 generated patterns. Whether this matters in practice, or if
1736 it's a good thing, or whether we should thread these new
1737 patterns into the define_insn chain just after their generator
1738 is something we'll have to experiment with. */
1740 queue_pattern (insn, &other_tail, insn_elem->loc);
1742 if (!insn_elem->split)
1743 continue;
1745 /* If the original insn came from a define_insn_and_split,
1746 generate a new split to handle the predicated insn. */
1747 split = copy_rtx (insn_elem->split->data);
1748 /* Predicate the pattern matched by the split. */
1749 pattern = rtx_alloc (COND_EXEC);
1750 XEXP (pattern, 0) = pred;
1751 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
1752 XVEC (split, 0) = rtvec_alloc (1);
1753 XVECEXP (split, 0, 0) = pattern;
1755 /* Predicate all of the insns generated by the split. */
1756 for (i = 0; i < XVECLEN (split, 2); i++)
1758 pattern = rtx_alloc (COND_EXEC);
1759 XEXP (pattern, 0) = pred;
1760 XEXP (pattern, 1) = XVECEXP (split, 2, i);
1761 XVECEXP (split, 2, i) = pattern;
1763 /* Add the new split to the queue. */
1764 queue_pattern (split, &other_tail, insn_elem->split->loc);
1768 /* Try to apply define_substs to the given ELEM.
1769 Only define_substs, specified via attributes would be applied.
1770 If attribute, requiring define_subst, is set, but no define_subst
1771 was applied, ELEM would be deleted. */
1773 static void
1774 process_substs_on_one_elem (struct queue_elem *elem,
1775 struct queue_elem *queue)
1777 struct queue_elem *subst_elem;
1778 int i, j, patterns_match;
1780 for (subst_elem = define_subst_queue;
1781 subst_elem; subst_elem = subst_elem->next)
1783 int alternatives, alternatives_subst;
1784 rtx subst_pattern;
1785 rtvec subst_pattern_vec;
1787 if (!has_subst_attribute (elem, subst_elem))
1788 continue;
1790 /* Compare original rtl-pattern from define_insn with input
1791 pattern from define_subst.
1792 Also, check if numbers of alternatives are the same in all
1793 match_operands. */
1794 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1795 continue;
1796 patterns_match = 1;
1797 alternatives = -1;
1798 alternatives_subst = -1;
1799 for (j = 0; j < XVECLEN (elem->data, 1); j++)
1801 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1802 XVECEXP (subst_elem->data, 1, j),
1803 subst_elem->loc))
1805 patterns_match = 0;
1806 break;
1809 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1810 &alternatives, subst_elem->loc))
1812 patterns_match = 0;
1813 break;
1817 /* Check if numbers of alternatives are the same in all
1818 match_operands in output template of define_subst. */
1819 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1821 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1822 &alternatives_subst,
1823 subst_elem->loc))
1825 patterns_match = 0;
1826 break;
1830 if (!patterns_match)
1831 continue;
1833 /* Clear array in which we save occupied indexes of operands. */
1834 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1836 /* Create a pattern, based on the output one from define_subst. */
1837 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1838 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1840 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1842 /* Duplicate constraints in substitute-pattern. */
1843 subst_pattern = alter_constraints (subst_pattern, alternatives,
1844 duplicate_each_alternative);
1846 subst_pattern = adjust_operands_numbers (subst_pattern);
1848 /* Substitute match_dup and match_op_dup in the new pattern and
1849 duplicate constraints. */
1850 subst_pattern = subst_dup (subst_pattern, alternatives,
1851 alternatives_subst);
1853 replace_duplicating_operands_in_pattern (subst_pattern);
1855 /* We don't need any constraints in DEFINE_EXPAND. */
1856 if (GET_CODE (elem->data) == DEFINE_EXPAND)
1857 remove_constraints (subst_pattern);
1859 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1861 XVEC (elem->data, 1) = subst_pattern_vec;
1863 for (i = 0; i < MAX_OPERANDS; i++)
1864 match_operand_entries_in_pattern[i] = NULL;
1866 if (GET_CODE (elem->data) == DEFINE_INSN)
1868 XTMPL (elem->data, 3) =
1869 alter_output_for_subst_insn (elem->data, alternatives_subst);
1870 alter_attrs_for_subst_insn (elem, alternatives_subst);
1873 /* Recalculate condition, joining conditions from original and
1874 DEFINE_SUBST input patterns. */
1875 XSTR (elem->data, 2)
1876 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
1877 XSTR (elem->data, 2));
1878 /* Mark that subst was applied by changing attribute from "yes"
1879 to "no". */
1880 change_subst_attribute (elem, subst_elem, subst_false);
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 /* FALLTHRU */
2160 case 'E':
2161 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2162 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2163 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2164 n_alt, n_subst_alt);
2165 break;
2167 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2168 break;
2170 default:
2171 gcc_unreachable ();
2174 return pattern;
2177 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2178 patterns appropriately. */
2180 static void
2181 process_define_cond_exec (void)
2183 struct queue_elem *elem;
2185 identify_predicable_attribute ();
2186 if (have_error)
2187 return;
2189 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2190 process_one_cond_exec (elem);
2193 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2194 DEFINE_EXPAND patterns appropriately. */
2196 static void
2197 process_define_subst (void)
2199 struct queue_elem *elem, *elem_attr;
2201 /* Check if each define_subst has corresponding define_subst_attr. */
2202 for (elem = define_subst_queue; elem ; elem = elem->next)
2204 for (elem_attr = define_subst_attr_queue;
2205 elem_attr;
2206 elem_attr = elem_attr->next)
2207 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2208 goto found;
2210 error_at (elem->loc,
2211 "%s: `define_subst' must have at least one "
2212 "corresponding `define_subst_attr'",
2213 XSTR (elem->data, 0));
2214 return;
2216 found:
2217 continue;
2220 for (elem = define_insn_queue; elem ; elem = elem->next)
2221 process_substs_on_one_elem (elem, define_insn_queue);
2222 for (elem = other_queue; elem ; elem = elem->next)
2224 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2225 continue;
2226 process_substs_on_one_elem (elem, other_queue);
2230 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2231 the top-level elements. */
2233 class gen_reader : public rtx_reader
2235 public:
2236 gen_reader () : rtx_reader (false) {}
2237 void handle_unknown_directive (file_location, const char *);
2240 void
2241 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2243 auto_vec<rtx, 32> subrtxs;
2244 if (!read_rtx (rtx_name, &subrtxs))
2245 return;
2247 rtx x;
2248 unsigned int i;
2249 FOR_EACH_VEC_ELT (subrtxs, i, x)
2250 process_rtx (x, loc);
2253 /* Comparison function for the mnemonic hash table. */
2255 static int
2256 htab_eq_string (const void *s1, const void *s2)
2258 return strcmp ((const char*)s1, (const char*)s2) == 0;
2261 /* Add mnemonic STR with length LEN to the mnemonic hash table
2262 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2263 and a permanent heap copy of STR is created. */
2265 static void
2266 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2268 char *new_str;
2269 void **slot;
2270 char *str_zero = (char*)alloca (len + 1);
2272 memcpy (str_zero, str, len);
2273 str_zero[len] = '\0';
2275 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2277 if (*slot)
2278 return;
2280 /* Not found; create a permanent copy and add it to the hash table. */
2281 new_str = XNEWVAR (char, len + 1);
2282 memcpy (new_str, str_zero, len + 1);
2283 *slot = new_str;
2286 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2287 table in MNEMONIC_HTAB.
2289 The mnemonics cannot be found if they are emitted using C code.
2291 If a mnemonic string contains ';' or a newline the string assumed
2292 to consist of more than a single instruction. The attribute value
2293 will then be set to the user defined default value. */
2295 static void
2296 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2298 const char *template_code, *cp;
2299 int i;
2300 int vec_len;
2301 rtx set_attr;
2302 char *attr_name;
2303 rtvec new_vec;
2304 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2306 template_code = XTMPL (insn, 3);
2308 /* Skip patterns which use C code to emit the template. */
2309 if (template_code[0] == '*')
2310 return;
2312 if (template_code[0] == '@')
2313 cp = &template_code[1];
2314 else
2315 cp = &template_code[0];
2317 for (i = 0; *cp; )
2319 const char *ep, *sp;
2320 size_t size = 0;
2322 while (ISSPACE (*cp))
2323 cp++;
2325 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2326 if (!ISSPACE (*ep))
2327 sp = ep + 1;
2329 if (i > 0)
2330 obstack_1grow (string_obstack, ',');
2332 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2333 || (*cp >= 'a' && *cp <= 'z')))
2336 obstack_1grow (string_obstack, *cp);
2337 cp++;
2338 size++;
2341 while (cp < sp)
2343 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2345 /* Don't set a value if there are more than one
2346 instruction in the string. */
2347 obstack_blank_fast (string_obstack, -size);
2348 size = 0;
2350 cp = sp;
2351 break;
2353 cp++;
2355 if (size == 0)
2356 obstack_1grow (string_obstack, '*');
2357 else
2358 add_mnemonic_string (mnemonic_htab,
2359 (char *) obstack_next_free (string_obstack) - size,
2360 size);
2361 i++;
2364 /* An insn definition might emit an empty string. */
2365 if (obstack_object_size (string_obstack) == 0)
2366 return;
2368 obstack_1grow (string_obstack, '\0');
2370 set_attr = rtx_alloc (SET_ATTR);
2371 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
2372 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2373 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2374 XSTR (set_attr, 0) = attr_name;
2376 if (!XVEC (insn, 4))
2377 vec_len = 0;
2378 else
2379 vec_len = XVECLEN (insn, 4);
2381 new_vec = rtvec_alloc (vec_len + 1);
2382 for (i = 0; i < vec_len; i++)
2383 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2384 RTVEC_ELT (new_vec, vec_len) = set_attr;
2385 XVEC (insn, 4) = new_vec;
2388 /* This function is called for the elements in the mnemonic hashtable
2389 and generates a comma separated list of the mnemonics. */
2391 static int
2392 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2394 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2396 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
2397 obstack_1grow (string_obstack, ',');
2398 return 1;
2401 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2402 insn definition in case the back end requests it by defining the
2403 mnemonic attribute. The values for the attribute will be extracted
2404 from the output patterns of the insn definitions as far as
2405 possible. */
2407 static void
2408 gen_mnemonic_attr (void)
2410 struct queue_elem *elem;
2411 rtx mnemonic_attr = NULL;
2412 htab_t mnemonic_htab;
2413 const char *str, *p;
2414 int i;
2415 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2417 if (have_error)
2418 return;
2420 /* Look for the DEFINE_ATTR for `mnemonic'. */
2421 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2422 if (GET_CODE (elem->data) == DEFINE_ATTR
2423 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2425 mnemonic_attr = elem->data;
2426 break;
2429 /* A (define_attr "mnemonic" "...") indicates that the back-end
2430 wants a mnemonic attribute to be generated. */
2431 if (!mnemonic_attr)
2432 return;
2434 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2435 htab_eq_string, 0, xcalloc, free);
2437 for (elem = define_insn_queue; elem; elem = elem->next)
2439 rtx insn = elem->data;
2440 bool found = false;
2442 /* Check if the insn definition already has
2443 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2444 if (XVEC (insn, 4))
2445 for (i = 0; i < XVECLEN (insn, 4); i++)
2447 rtx set_attr = XVECEXP (insn, 4, i);
2449 switch (GET_CODE (set_attr))
2451 case SET_ATTR:
2452 case SET_ATTR_ALTERNATIVE:
2453 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
2454 found = true;
2455 break;
2456 case SET:
2457 if (GET_CODE (SET_DEST (set_attr)) == ATTR
2458 && strcmp (XSTR (SET_DEST (set_attr), 0),
2459 MNEMONIC_ATTR_NAME) == 0)
2460 found = true;
2461 break;
2462 default:
2463 break;
2467 if (!found)
2468 gen_mnemonic_setattr (mnemonic_htab, insn);
2471 /* Add the user defined values to the hash table. */
2472 str = XSTR (mnemonic_attr, 1);
2473 while ((p = scan_comma_elt (&str)) != NULL)
2474 add_mnemonic_string (mnemonic_htab, p, str - p);
2476 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2478 /* Replace the last ',' with the zero end character. */
2479 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
2480 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
2483 /* Check if there are DEFINE_ATTRs with the same name. */
2484 static void
2485 check_define_attr_duplicates ()
2487 struct queue_elem *elem;
2488 htab_t attr_htab;
2489 char * attr_name;
2490 void **slot;
2492 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2494 for (elem = define_attr_queue; elem; elem = elem->next)
2496 attr_name = xstrdup (XSTR (elem->data, 0));
2498 slot = htab_find_slot (attr_htab, attr_name, INSERT);
2500 /* Duplicate. */
2501 if (*slot)
2503 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
2504 htab_delete (attr_htab);
2505 return;
2508 *slot = attr_name;
2511 htab_delete (attr_htab);
2514 /* The entry point for initializing the reader. */
2516 rtx_reader *
2517 init_rtx_reader_args_cb (int argc, const char **argv,
2518 bool (*parse_opt) (const char *))
2520 /* Prepare to read input. */
2521 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2522 init_predicate_table ();
2523 obstack_init (rtl_obstack);
2525 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2526 insn_sequence_num = 1;
2528 /* These sequences are not used as indices, so can start at 1 also. */
2529 split_sequence_num = 1;
2530 peephole2_sequence_num = 1;
2532 gen_reader *reader = new gen_reader ();
2533 reader->read_md_files (argc, argv, parse_opt);
2535 if (define_attr_queue != NULL)
2536 check_define_attr_duplicates ();
2538 /* Process define_cond_exec patterns. */
2539 if (define_cond_exec_queue != NULL)
2540 process_define_cond_exec ();
2542 /* Process define_subst patterns. */
2543 if (define_subst_queue != NULL)
2544 process_define_subst ();
2546 if (define_attr_queue != NULL)
2547 gen_mnemonic_attr ();
2549 if (have_error)
2551 delete reader;
2552 return NULL;
2555 return reader;
2558 /* Programs that don't have their own options can use this entry point
2559 instead. */
2560 rtx_reader *
2561 init_rtx_reader_args (int argc, const char **argv)
2563 return init_rtx_reader_args_cb (argc, argv, 0);
2566 /* Try to read a single rtx from the file. Return true on success,
2567 describing it in *INFO. */
2569 bool
2570 read_md_rtx (md_rtx_info *info)
2572 int truth, *counter;
2573 rtx def;
2575 /* Discard insn patterns which we know can never match (because
2576 their C test is provably always false). If insn_elision is
2577 false, our caller needs to see all the patterns. Note that the
2578 elided patterns are never counted by the sequence numbering; it
2579 is the caller's responsibility, when insn_elision is false, not
2580 to use elided pattern numbers for anything. */
2583 struct queue_elem **queue, *elem;
2585 /* Read all patterns from a given queue before moving on to the next. */
2586 if (define_attr_queue != NULL)
2587 queue = &define_attr_queue;
2588 else if (define_pred_queue != NULL)
2589 queue = &define_pred_queue;
2590 else if (define_insn_queue != NULL)
2591 queue = &define_insn_queue;
2592 else if (other_queue != NULL)
2593 queue = &other_queue;
2594 else
2595 return false;
2597 elem = *queue;
2598 *queue = elem->next;
2599 def = elem->data;
2600 info->def = def;
2601 info->loc = elem->loc;
2602 free (elem);
2604 truth = maybe_eval_c_test (get_c_test (def));
2606 while (truth == 0 && insn_elision);
2608 /* Perform code-specific processing and pick the appropriate sequence
2609 number counter. */
2610 switch (GET_CODE (def))
2612 case DEFINE_INSN:
2613 case DEFINE_EXPAND:
2614 /* insn_sequence_num is used here so the name table will match caller's
2615 idea of insn numbering, whether or not elision is active. */
2616 record_insn_name (insn_sequence_num, XSTR (def, 0));
2618 /* Fall through. */
2619 case DEFINE_PEEPHOLE:
2620 counter = &insn_sequence_num;
2621 break;
2623 case DEFINE_SPLIT:
2624 counter = &split_sequence_num;
2625 break;
2627 case DEFINE_PEEPHOLE2:
2628 counter = &peephole2_sequence_num;
2629 break;
2631 default:
2632 counter = NULL;
2633 break;
2636 if (counter)
2638 info->index = *counter;
2639 if (truth != 0)
2640 *counter += 1;
2642 else
2643 info->index = -1;
2645 if (!rtx_locs)
2646 rtx_locs = new hash_map <rtx, file_location>;
2647 rtx_locs->put (info->def, info->loc);
2649 return true;
2652 /* Return the file location of DEFINE_* rtx X, which was previously
2653 returned by read_md_rtx. */
2654 file_location
2655 get_file_location (rtx x)
2657 gcc_assert (rtx_locs);
2658 file_location *entry = rtx_locs->get (x);
2659 gcc_assert (entry);
2660 return *entry;
2663 /* Return the number of possible INSN_CODEs. Only meaningful once the
2664 whole file has been processed. */
2665 unsigned int
2666 get_num_insn_codes ()
2668 return insn_sequence_num;
2671 /* Return the C test that says whether definition rtx DEF can be used,
2672 or "" if it can be used unconditionally. */
2674 const char *
2675 get_c_test (rtx x)
2677 switch (GET_CODE (x))
2679 case DEFINE_INSN:
2680 case DEFINE_EXPAND:
2681 case DEFINE_SUBST:
2682 return XSTR (x, 2);
2684 case DEFINE_SPLIT:
2685 case DEFINE_PEEPHOLE:
2686 case DEFINE_PEEPHOLE2:
2687 return XSTR (x, 1);
2689 default:
2690 return "";
2694 /* Helper functions for insn elision. */
2696 /* Compute a hash function of a c_test structure, which is keyed
2697 by its ->expr field. */
2698 hashval_t
2699 hash_c_test (const void *x)
2701 const struct c_test *a = (const struct c_test *) x;
2702 const unsigned char *base, *s = (const unsigned char *) a->expr;
2703 hashval_t hash;
2704 unsigned char c;
2705 unsigned int len;
2707 base = s;
2708 hash = 0;
2710 while ((c = *s++) != '\0')
2712 hash += c + (c << 17);
2713 hash ^= hash >> 2;
2716 len = s - base;
2717 hash += len + (len << 17);
2718 hash ^= hash >> 2;
2720 return hash;
2723 /* Compare two c_test expression structures. */
2725 cmp_c_test (const void *x, const void *y)
2727 const struct c_test *a = (const struct c_test *) x;
2728 const struct c_test *b = (const struct c_test *) y;
2730 return !strcmp (a->expr, b->expr);
2733 /* Given a string representing a C test expression, look it up in the
2734 condition_table and report whether or not its value is known
2735 at compile time. Returns a tristate: 1 for known true, 0 for
2736 known false, -1 for unknown. */
2738 maybe_eval_c_test (const char *expr)
2740 const struct c_test *test;
2741 struct c_test dummy;
2743 if (expr[0] == 0)
2744 return 1;
2746 dummy.expr = expr;
2747 test = (const struct c_test *)htab_find (condition_table, &dummy);
2748 if (!test)
2749 return -1;
2750 return test->value;
2753 /* Record the C test expression EXPR in the condition_table, with
2754 value VAL. Duplicates clobber previous entries. */
2756 void
2757 add_c_test (const char *expr, int value)
2759 struct c_test *test;
2761 if (expr[0] == 0)
2762 return;
2764 test = XNEW (struct c_test);
2765 test->expr = expr;
2766 test->value = value;
2768 *(htab_find_slot (condition_table, test, INSERT)) = test;
2771 /* For every C test, call CALLBACK with two arguments: a pointer to
2772 the condition structure and INFO. Stops when CALLBACK returns zero. */
2773 void
2774 traverse_c_tests (htab_trav callback, void *info)
2776 if (condition_table)
2777 htab_traverse (condition_table, callback, info);
2780 /* Helper functions for define_predicate and define_special_predicate
2781 processing. Shared between genrecog.c and genpreds.c. */
2783 static htab_t predicate_table;
2784 struct pred_data *first_predicate;
2785 static struct pred_data **last_predicate = &first_predicate;
2787 static hashval_t
2788 hash_struct_pred_data (const void *ptr)
2790 return htab_hash_string (((const struct pred_data *)ptr)->name);
2793 static int
2794 eq_struct_pred_data (const void *a, const void *b)
2796 return !strcmp (((const struct pred_data *)a)->name,
2797 ((const struct pred_data *)b)->name);
2800 struct pred_data *
2801 lookup_predicate (const char *name)
2803 struct pred_data key;
2804 key.name = name;
2805 return (struct pred_data *) htab_find (predicate_table, &key);
2808 /* Record that predicate PRED can accept CODE. */
2810 void
2811 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2813 if (!pred->codes[code])
2815 pred->num_codes++;
2816 pred->codes[code] = true;
2818 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2819 pred->allows_non_const = true;
2821 if (code != REG
2822 && code != SUBREG
2823 && code != MEM
2824 && code != CONCAT
2825 && code != PARALLEL
2826 && code != STRICT_LOW_PART
2827 && code != SCRATCH)
2828 pred->allows_non_lvalue = true;
2830 if (pred->num_codes == 1)
2831 pred->singleton = code;
2832 else if (pred->num_codes == 2)
2833 pred->singleton = UNKNOWN;
2837 void
2838 add_predicate (struct pred_data *pred)
2840 void **slot = htab_find_slot (predicate_table, pred, INSERT);
2841 if (*slot)
2843 error ("duplicate predicate definition for '%s'", pred->name);
2844 return;
2846 *slot = pred;
2847 *last_predicate = pred;
2848 last_predicate = &pred->next;
2851 /* This array gives the initial content of the predicate table. It
2852 has entries for all predicates defined in recog.c. */
2854 struct std_pred_table
2856 const char *name;
2857 bool special;
2858 bool allows_const_p;
2859 RTX_CODE codes[NUM_RTX_CODE];
2862 static const struct std_pred_table std_preds[] = {
2863 {"general_operand", false, true, {SUBREG, REG, MEM}},
2864 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
2865 ZERO_EXTEND, SIGN_EXTEND, AND}},
2866 {"register_operand", false, false, {SUBREG, REG}},
2867 {"pmode_register_operand", true, false, {SUBREG, REG}},
2868 {"scratch_operand", false, false, {SCRATCH, REG}},
2869 {"immediate_operand", false, true, {UNKNOWN}},
2870 {"const_int_operand", false, false, {CONST_INT}},
2871 #if TARGET_SUPPORTS_WIDE_INT
2872 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
2873 {"const_double_operand", false, false, {CONST_DOUBLE}},
2874 #else
2875 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2876 #endif
2877 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2878 {"nonmemory_operand", false, true, {SUBREG, REG}},
2879 {"push_operand", false, false, {MEM}},
2880 {"pop_operand", false, false, {MEM}},
2881 {"memory_operand", false, false, {SUBREG, MEM}},
2882 {"indirect_operand", false, false, {SUBREG, MEM}},
2883 {"ordered_comparison_operator", false, false, {EQ, NE,
2884 LE, LT, GE, GT,
2885 LEU, LTU, GEU, GTU}},
2886 {"comparison_operator", false, false, {EQ, NE,
2887 LE, LT, GE, GT,
2888 LEU, LTU, GEU, GTU,
2889 UNORDERED, ORDERED,
2890 UNEQ, UNGE, UNGT,
2891 UNLE, UNLT, LTGT}}
2893 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2895 /* Initialize the table of predicate definitions, starting with
2896 the information we have on generic predicates. */
2898 static void
2899 init_predicate_table (void)
2901 size_t i, j;
2902 struct pred_data *pred;
2904 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2905 eq_struct_pred_data, 0,
2906 xcalloc, free);
2908 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2910 pred = XCNEW (struct pred_data);
2911 pred->name = std_preds[i].name;
2912 pred->special = std_preds[i].special;
2914 for (j = 0; std_preds[i].codes[j] != 0; j++)
2915 add_predicate_code (pred, std_preds[i].codes[j]);
2917 if (std_preds[i].allows_const_p)
2918 for (j = 0; j < NUM_RTX_CODE; j++)
2919 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2920 add_predicate_code (pred, (enum rtx_code) j);
2922 add_predicate (pred);
2926 /* These functions allow linkage with print-rtl.c. Also, some generators
2927 like to annotate their output with insn names. */
2929 /* Holds an array of names indexed by insn_code_number. */
2930 static char **insn_name_ptr = 0;
2931 static int insn_name_ptr_size = 0;
2933 const char *
2934 get_insn_name (int code)
2936 if (code < insn_name_ptr_size)
2937 return insn_name_ptr[code];
2938 else
2939 return NULL;
2942 static void
2943 record_insn_name (int code, const char *name)
2945 static const char *last_real_name = "insn";
2946 static int last_real_code = 0;
2947 char *new_name;
2949 if (insn_name_ptr_size <= code)
2951 int new_size;
2952 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
2953 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
2954 memset (insn_name_ptr + insn_name_ptr_size, 0,
2955 sizeof (char *) * (new_size - insn_name_ptr_size));
2956 insn_name_ptr_size = new_size;
2959 if (!name || name[0] == '\0')
2961 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
2962 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
2964 else
2966 last_real_name = new_name = xstrdup (name);
2967 last_real_code = code;
2970 insn_name_ptr[code] = new_name;
2973 /* Make STATS describe the operands that appear in rtx X. */
2975 static void
2976 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
2978 RTX_CODE code;
2979 int i;
2980 int len;
2981 const char *fmt;
2983 if (x == NULL_RTX)
2984 return;
2986 code = GET_CODE (x);
2987 switch (code)
2989 case MATCH_OPERAND:
2990 case MATCH_OPERATOR:
2991 case MATCH_PARALLEL:
2992 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
2993 break;
2995 case MATCH_DUP:
2996 case MATCH_OP_DUP:
2997 case MATCH_PAR_DUP:
2998 stats->num_dups++;
2999 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
3000 break;
3002 case MATCH_SCRATCH:
3003 if (stats->min_scratch_opno == -1)
3004 stats->min_scratch_opno = XINT (x, 0);
3005 else
3006 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
3007 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
3008 break;
3010 default:
3011 break;
3014 fmt = GET_RTX_FORMAT (code);
3015 len = GET_RTX_LENGTH (code);
3016 for (i = 0; i < len; i++)
3018 if (fmt[i] == 'e' || fmt[i] == 'u')
3019 get_pattern_stats_1 (stats, XEXP (x, i));
3020 else if (fmt[i] == 'E')
3022 int j;
3023 for (j = 0; j < XVECLEN (x, i); j++)
3024 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3029 /* Make STATS describe the operands that appear in instruction pattern
3030 PATTERN. */
3032 void
3033 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3035 int i, len;
3037 stats->max_opno = -1;
3038 stats->max_dup_opno = -1;
3039 stats->min_scratch_opno = -1;
3040 stats->max_scratch_opno = -1;
3041 stats->num_dups = 0;
3043 len = GET_NUM_ELEM (pattern);
3044 for (i = 0; i < len; i++)
3045 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3047 stats->num_generator_args = stats->max_opno + 1;
3048 stats->num_insn_operands = MAX (stats->max_opno,
3049 stats->max_scratch_opno) + 1;
3050 stats->num_operand_vars = MAX (stats->max_opno,
3051 MAX (stats->max_dup_opno,
3052 stats->max_scratch_opno)) + 1;
3055 /* Return the emit_* function that should be used for pattern X, or NULL
3056 if we can't pick a particular type at compile time and should instead
3057 fall back to "emit". */
3059 const char *
3060 get_emit_function (rtx x)
3062 switch (classify_insn (x))
3064 case INSN:
3065 return "emit_insn";
3067 case CALL_INSN:
3068 return "emit_call_insn";
3070 case JUMP_INSN:
3071 return "emit_jump_insn";
3073 case UNKNOWN:
3074 return NULL;
3076 default:
3077 gcc_unreachable ();
3081 /* Return true if we must emit a barrier after pattern X. */
3083 bool
3084 needs_barrier_p (rtx x)
3086 return (GET_CODE (x) == SET
3087 && GET_CODE (SET_DEST (x)) == PC
3088 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3091 #define NS "NULL"
3092 #define ZS "'\\0'"
3093 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3094 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3095 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3096 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3097 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3098 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3099 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3100 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3101 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3102 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3103 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3105 /* An array of all optabs. Note that the same optab can appear more
3106 than once, with a different pattern. */
3107 optab_def optabs[] = {
3108 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3109 #include "optabs.def"
3112 /* The number of entries in optabs[]. */
3113 unsigned int num_optabs = ARRAY_SIZE (optabs);
3115 #undef OPTAB_CL
3116 #undef OPTAB_CX
3117 #undef OPTAB_CD
3118 #undef OPTAB_NL
3119 #undef OPTAB_NC
3120 #undef OPTAB_NX
3121 #undef OPTAB_VL
3122 #undef OPTAB_VC
3123 #undef OPTAB_VX
3124 #undef OPTAB_DC
3125 #undef OPTAB_D
3127 /* Return true if instruction NAME matches pattern PAT, storing information
3128 about the match in P if so. */
3130 static bool
3131 match_pattern (optab_pattern *p, const char *name, const char *pat)
3133 bool force_float = false;
3134 bool force_int = false;
3135 bool force_partial_int = false;
3136 bool force_fixed = false;
3138 if (pat == NULL)
3139 return false;
3140 for (; ; ++pat)
3142 if (*pat != '$')
3144 if (*pat != *name++)
3145 return false;
3146 if (*pat == '\0')
3147 return true;
3148 continue;
3150 switch (*++pat)
3152 case 'I':
3153 force_int = 1;
3154 break;
3155 case 'P':
3156 force_partial_int = 1;
3157 break;
3158 case 'F':
3159 force_float = 1;
3160 break;
3161 case 'Q':
3162 force_fixed = 1;
3163 break;
3165 case 'a':
3166 case 'b':
3168 int i;
3170 /* This loop will stop at the first prefix match, so
3171 look through the modes in reverse order, in case
3172 there are extra CC modes and CC is a prefix of the
3173 CC modes (as it should be). */
3174 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3176 const char *p, *q;
3177 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3178 if (TOLOWER (*p) != *q)
3179 break;
3180 if (*p == 0
3181 && (! force_int || mode_class[i] == MODE_INT
3182 || mode_class[i] == MODE_VECTOR_INT)
3183 && (! force_partial_int
3184 || mode_class[i] == MODE_INT
3185 || mode_class[i] == MODE_PARTIAL_INT
3186 || mode_class[i] == MODE_VECTOR_INT)
3187 && (! force_float
3188 || mode_class[i] == MODE_FLOAT
3189 || mode_class[i] == MODE_DECIMAL_FLOAT
3190 || mode_class[i] == MODE_COMPLEX_FLOAT
3191 || mode_class[i] == MODE_VECTOR_FLOAT)
3192 && (! force_fixed
3193 || mode_class[i] == MODE_FRACT
3194 || mode_class[i] == MODE_UFRACT
3195 || mode_class[i] == MODE_ACCUM
3196 || mode_class[i] == MODE_UACCUM
3197 || mode_class[i] == MODE_VECTOR_FRACT
3198 || mode_class[i] == MODE_VECTOR_UFRACT
3199 || mode_class[i] == MODE_VECTOR_ACCUM
3200 || mode_class[i] == MODE_VECTOR_UACCUM))
3201 break;
3204 if (i < 0)
3205 return false;
3206 name += strlen (GET_MODE_NAME (i));
3207 if (*pat == 'a')
3208 p->m1 = i;
3209 else
3210 p->m2 = i;
3212 force_int = false;
3213 force_partial_int = false;
3214 force_float = false;
3215 force_fixed = false;
3217 break;
3219 default:
3220 gcc_unreachable ();
3225 /* Return true if NAME is the name of an optab, describing it in P if so. */
3227 bool
3228 find_optab (optab_pattern *p, const char *name)
3230 if (*name == 0 || *name == '*')
3231 return false;
3233 /* See if NAME matches one of the patterns we have for the optabs
3234 we know about. */
3235 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3237 p->m1 = p->m2 = 0;
3238 if (match_pattern (p, name, optabs[pindex].pattern))
3240 p->name = name;
3241 p->op = optabs[pindex].op;
3242 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
3243 return true;
3246 return false;