comparison gcc/gensupport.c @ 16:04ced10e8804

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