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