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