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