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