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