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