]>
Commit | Line | Data |
---|---|---|
ec65fa66 | 1 | /* Generate code from machine description to recognize rtl as insns. |
d050d723 | 2 | Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, |
bbbbb16a | 3 | 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 |
9dcd6f09 | 4 | Free Software Foundation, Inc. |
ec65fa66 | 5 | |
1322177d | 6 | This file is part of GCC. |
09051660 | 7 | |
1322177d LB |
8 | GCC is free software; you can redistribute it and/or modify it |
9 | under the terms of the GNU General Public License as published by | |
9dcd6f09 | 10 | the Free Software Foundation; either version 3, or (at your option) |
09051660 RH |
11 | any later version. |
12 | ||
1322177d LB |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT |
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
16 | License for more details. | |
09051660 RH |
17 | |
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
09051660 RH |
21 | |
22 | ||
23 | /* This program is used to produce insn-recog.c, which contains a | |
24 | function called `recog' plus its subroutines. These functions | |
25 | contain a decision tree that recognizes whether an rtx, the | |
26 | argument given to recog, is a valid instruction. | |
27 | ||
28 | recog returns -1 if the rtx is not valid. If the rtx is valid, | |
29 | recog returns a nonnegative number which is the insn code number | |
30 | for the pattern that matched. This is the same as the order in the | |
31 | machine description of the entry that matched. This number can be | |
32 | used as an index into various insn_* tables, such as insn_template, | |
33 | insn_outfun, and insn_n_operands (found in insn-output.c). | |
34 | ||
35 | The third argument to recog is an optional pointer to an int. If | |
36 | present, recog will accept a pattern if it matches except for | |
ec65fa66 RK |
37 | missing CLOBBER expressions at the end. In that case, the value |
38 | pointed to by the optional pointer will be set to the number of | |
39 | CLOBBERs that need to be added (it should be initialized to zero by | |
40 | the caller). If it is set nonzero, the caller should allocate a | |
09051660 RH |
41 | PARALLEL of the appropriate size, copy the initial entries, and |
42 | call add_clobbers (found in insn-emit.c) to fill in the CLOBBERs. | |
ec65fa66 | 43 | |
09051660 RH |
44 | This program also generates the function `split_insns', which |
45 | returns 0 if the rtl could not be split, or it returns the split | |
2f937369 | 46 | rtl as an INSN list. |
09051660 RH |
47 | |
48 | This program also generates the function `peephole2_insns', which | |
49 | returns 0 if the rtl could not be matched. If there was a match, | |
2f937369 | 50 | the new rtl is returned in an INSN list, and LAST_INSN will point |
09051660 | 51 | to the last recognized insn in the old sequence. */ |
ec65fa66 | 52 | |
4977bab6 | 53 | #include "bconfig.h" |
0b93b64e | 54 | #include "system.h" |
4977bab6 ZW |
55 | #include "coretypes.h" |
56 | #include "tm.h" | |
ec65fa66 | 57 | #include "rtl.h" |
f8b6598e | 58 | #include "errors.h" |
10692477 | 59 | #include "read-md.h" |
c88c0d42 | 60 | #include "gensupport.h" |
ec65fa66 | 61 | |
736b02fd KG |
62 | #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \ |
63 | printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER)) | |
64 | ||
09051660 | 65 | /* A listhead of decision trees. The alternatives to a node are kept |
fbe5a4a6 | 66 | in a doubly-linked list so we can easily add nodes to the proper |
09051660 RH |
67 | place when merging. */ |
68 | ||
69 | struct decision_head | |
70 | { | |
71 | struct decision *first; | |
72 | struct decision *last; | |
73 | }; | |
5b7c7046 | 74 | |
24b97832 ILT |
75 | /* These types are roughly in the order in which we'd like to test them. */ |
76 | enum decision_type | |
77 | { | |
78 | DT_num_insns, | |
79 | DT_mode, DT_code, DT_veclen, | |
80 | DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe, | |
81 | DT_const_int, | |
82 | DT_veclen_ge, DT_dup, DT_pred, DT_c_test, | |
83 | DT_accept_op, DT_accept_insn | |
84 | }; | |
85 | ||
09051660 RH |
86 | /* A single test. The two accept types aren't tests per-se, but |
87 | their equality (or lack thereof) does affect tree merging so | |
88 | it is convenient to keep them here. */ | |
89 | ||
90 | struct decision_test | |
91 | { | |
92 | /* A linked list through the tests attached to a node. */ | |
93 | struct decision_test *next; | |
94 | ||
24b97832 | 95 | enum decision_type type; |
09051660 RH |
96 | |
97 | union | |
98 | { | |
0cd6c85a | 99 | int num_insns; /* Number if insn in a define_peephole2. */ |
09051660 RH |
100 | enum machine_mode mode; /* Machine mode of node. */ |
101 | RTX_CODE code; /* Code to test. */ | |
e0689256 | 102 | |
09051660 RH |
103 | struct |
104 | { | |
105 | const char *name; /* Predicate to call. */ | |
e543e219 ZW |
106 | const struct pred_data *data; |
107 | /* Optimization hints for this predicate. */ | |
09051660 RH |
108 | enum machine_mode mode; /* Machine mode for node. */ |
109 | } pred; | |
110 | ||
111 | const char *c_test; /* Additional test to perform. */ | |
112 | int veclen; /* Length of vector. */ | |
113 | int dup; /* Number of operand to compare against. */ | |
114 | HOST_WIDE_INT intval; /* Value for XINT for XWINT. */ | |
115 | int opno; /* Operand number matched. */ | |
116 | ||
117 | struct { | |
118 | int code_number; /* Insn number matched. */ | |
bcdaba58 | 119 | int lineno; /* Line number of the insn. */ |
09051660 RH |
120 | int num_clobbers_to_add; /* Number of CLOBBERs to be added. */ |
121 | } insn; | |
122 | } u; | |
123 | }; | |
e0689256 | 124 | |
09051660 | 125 | /* Data structure for decision tree for recognizing legitimate insns. */ |
ec65fa66 RK |
126 | |
127 | struct decision | |
128 | { | |
09051660 RH |
129 | struct decision_head success; /* Nodes to test on success. */ |
130 | struct decision *next; /* Node to test on failure. */ | |
131 | struct decision *prev; /* Node whose failure tests us. */ | |
132 | struct decision *afterward; /* Node to test on success, | |
133 | but failure of successor nodes. */ | |
134 | ||
135 | const char *position; /* String denoting position in pattern. */ | |
136 | ||
137 | struct decision_test *tests; /* The tests for this node. */ | |
138 | ||
e0689256 | 139 | int number; /* Node number, used for labels */ |
e0689256 | 140 | int subroutine_number; /* Number of subroutine this node starts */ |
09051660 | 141 | int need_label; /* Label needs to be output. */ |
ec65fa66 RK |
142 | }; |
143 | ||
09051660 | 144 | #define SUBROUTINE_THRESHOLD 100 |
ec65fa66 RK |
145 | |
146 | static int next_subroutine_number; | |
147 | ||
ede7cd44 RH |
148 | /* We can write three types of subroutines: One for insn recognition, |
149 | one to split insns, and one for peephole-type optimizations. This | |
150 | defines which type is being written. */ | |
ec65fa66 | 151 | |
09051660 RH |
152 | enum routine_type { |
153 | RECOG, SPLIT, PEEPHOLE2 | |
154 | }; | |
ede7cd44 | 155 | |
09051660 | 156 | #define IS_SPLIT(X) ((X) != RECOG) |
ec65fa66 | 157 | |
e0689256 | 158 | /* Next available node number for tree nodes. */ |
ec65fa66 | 159 | |
e0689256 | 160 | static int next_number; |
ec65fa66 | 161 | |
e0689256 | 162 | /* Next number to use as an insn_code. */ |
ec65fa66 | 163 | |
e0689256 | 164 | static int next_insn_code; |
ec65fa66 | 165 | |
e0689256 RK |
166 | /* Record the highest depth we ever have so we know how many variables to |
167 | allocate in each subroutine we make. */ | |
ec65fa66 | 168 | |
e0689256 | 169 | static int max_depth; |
bcdaba58 RH |
170 | |
171 | /* The line number of the start of the pattern currently being processed. */ | |
172 | static int pattern_lineno; | |
e0689256 | 173 | \f |
5abc5de9 | 174 | /* Predicate handling. |
e543e219 ZW |
175 | |
176 | We construct from the machine description a table mapping each | |
177 | predicate to a list of the rtl codes it can possibly match. The | |
178 | function 'maybe_both_true' uses it to deduce that there are no | |
179 | expressions that can be matches by certain pairs of tree nodes. | |
180 | Also, if a predicate can match only one code, we can hardwire that | |
181 | code into the node testing the predicate. | |
182 | ||
183 | Some predicates are flagged as special. validate_pattern will not | |
184 | warn about modeless match_operand expressions if they have a | |
185 | special predicate. Predicates that allow only constants are also | |
186 | treated as special, for this purpose. | |
187 | ||
188 | validate_pattern will warn about predicates that allow non-lvalues | |
189 | when they appear in destination operands. | |
190 | ||
191 | Calculating the set of rtx codes that can possibly be accepted by a | |
192 | predicate expression EXP requires a three-state logic: any given | |
193 | subexpression may definitively accept a code C (Y), definitively | |
194 | reject a code C (N), or may have an indeterminate effect (I). N | |
195 | and I is N; Y or I is Y; Y and I, N or I are both I. Here are full | |
196 | truth tables. | |
197 | ||
198 | a b a&b a|b | |
199 | Y Y Y Y | |
200 | N Y N Y | |
201 | N N N N | |
202 | I Y I Y | |
203 | I N N I | |
204 | I I I I | |
205 | ||
206 | We represent Y with 1, N with 0, I with 2. If any code is left in | |
207 | an I state by the complete expression, we must assume that that | |
208 | code can be accepted. */ | |
209 | ||
210 | #define N 0 | |
211 | #define Y 1 | |
212 | #define I 2 | |
213 | ||
214 | #define TRISTATE_AND(a,b) \ | |
215 | ((a) == I ? ((b) == N ? N : I) : \ | |
216 | (b) == I ? ((a) == N ? N : I) : \ | |
217 | (a) && (b)) | |
218 | ||
219 | #define TRISTATE_OR(a,b) \ | |
220 | ((a) == I ? ((b) == Y ? Y : I) : \ | |
221 | (b) == I ? ((a) == Y ? Y : I) : \ | |
222 | (a) || (b)) | |
223 | ||
224 | #define TRISTATE_NOT(a) \ | |
225 | ((a) == I ? I : !(a)) | |
226 | ||
603b6b88 DD |
227 | /* 0 means no warning about that code yet, 1 means warned. */ |
228 | static char did_you_mean_codes[NUM_RTX_CODE]; | |
229 | ||
e543e219 ZW |
230 | /* Recursively calculate the set of rtx codes accepted by the |
231 | predicate expression EXP, writing the result to CODES. */ | |
232 | static void | |
233 | compute_predicate_codes (rtx exp, char codes[NUM_RTX_CODE]) | |
234 | { | |
235 | char op0_codes[NUM_RTX_CODE]; | |
236 | char op1_codes[NUM_RTX_CODE]; | |
237 | char op2_codes[NUM_RTX_CODE]; | |
238 | int i; | |
239 | ||
240 | switch (GET_CODE (exp)) | |
241 | { | |
242 | case AND: | |
243 | compute_predicate_codes (XEXP (exp, 0), op0_codes); | |
244 | compute_predicate_codes (XEXP (exp, 1), op1_codes); | |
245 | for (i = 0; i < NUM_RTX_CODE; i++) | |
246 | codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]); | |
247 | break; | |
248 | ||
249 | case IOR: | |
250 | compute_predicate_codes (XEXP (exp, 0), op0_codes); | |
251 | compute_predicate_codes (XEXP (exp, 1), op1_codes); | |
252 | for (i = 0; i < NUM_RTX_CODE; i++) | |
253 | codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]); | |
254 | break; | |
255 | case NOT: | |
256 | compute_predicate_codes (XEXP (exp, 0), op0_codes); | |
257 | for (i = 0; i < NUM_RTX_CODE; i++) | |
4c80d5ac | 258 | codes[i] = TRISTATE_NOT (op0_codes[i]); |
e543e219 ZW |
259 | break; |
260 | ||
261 | case IF_THEN_ELSE: | |
5abc5de9 | 262 | /* a ? b : c accepts the same codes as (a & b) | (!a & c). */ |
e543e219 ZW |
263 | compute_predicate_codes (XEXP (exp, 0), op0_codes); |
264 | compute_predicate_codes (XEXP (exp, 1), op1_codes); | |
265 | compute_predicate_codes (XEXP (exp, 2), op2_codes); | |
266 | for (i = 0; i < NUM_RTX_CODE; i++) | |
267 | codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]), | |
268 | TRISTATE_AND (TRISTATE_NOT (op0_codes[i]), | |
269 | op2_codes[i])); | |
270 | break; | |
271 | ||
272 | case MATCH_CODE: | |
6e7a4706 ZW |
273 | /* MATCH_CODE allows a specified list of codes. However, if it |
274 | does not apply to the top level of the expression, it does not | |
275 | constrain the set of codes for the top level. */ | |
276 | if (XSTR (exp, 1)[0] != '\0') | |
277 | { | |
278 | memset (codes, Y, NUM_RTX_CODE); | |
279 | break; | |
280 | } | |
281 | ||
e543e219 ZW |
282 | memset (codes, N, NUM_RTX_CODE); |
283 | { | |
284 | const char *next_code = XSTR (exp, 0); | |
285 | const char *code; | |
ec65fa66 | 286 | |
e543e219 ZW |
287 | if (*next_code == '\0') |
288 | { | |
bb933490 | 289 | error_with_line (pattern_lineno, "empty match_code expression"); |
e543e219 ZW |
290 | break; |
291 | } | |
292 | ||
293 | while ((code = scan_comma_elt (&next_code)) != 0) | |
294 | { | |
295 | size_t n = next_code - code; | |
603b6b88 | 296 | int found_it = 0; |
5abc5de9 | 297 | |
e543e219 ZW |
298 | for (i = 0; i < NUM_RTX_CODE; i++) |
299 | if (!strncmp (code, GET_RTX_NAME (i), n) | |
300 | && GET_RTX_NAME (i)[n] == '\0') | |
301 | { | |
302 | codes[i] = Y; | |
603b6b88 | 303 | found_it = 1; |
e543e219 ZW |
304 | break; |
305 | } | |
603b6b88 DD |
306 | if (!found_it) |
307 | { | |
bb933490 RS |
308 | error_with_line (pattern_lineno, |
309 | "match_code \"%.*s\" matches nothing", | |
310 | (int) n, code); | |
603b6b88 DD |
311 | for (i = 0; i < NUM_RTX_CODE; i++) |
312 | if (!strncasecmp (code, GET_RTX_NAME (i), n) | |
313 | && GET_RTX_NAME (i)[n] == '\0' | |
314 | && !did_you_mean_codes[i]) | |
315 | { | |
316 | did_you_mean_codes[i] = 1; | |
317 | message_with_line (pattern_lineno, "(did you mean \"%s\"?)", GET_RTX_NAME (i)); | |
318 | } | |
319 | } | |
320 | ||
e543e219 ZW |
321 | } |
322 | } | |
323 | break; | |
324 | ||
325 | case MATCH_OPERAND: | |
326 | /* MATCH_OPERAND disallows the set of codes that the named predicate | |
327 | disallows, and is indeterminate for the codes that it does allow. */ | |
328 | { | |
329 | struct pred_data *p = lookup_predicate (XSTR (exp, 1)); | |
330 | if (!p) | |
331 | { | |
bb933490 RS |
332 | error_with_line (pattern_lineno, |
333 | "reference to unknown predicate '%s'", | |
334 | XSTR (exp, 1)); | |
e543e219 ZW |
335 | break; |
336 | } | |
337 | for (i = 0; i < NUM_RTX_CODE; i++) | |
338 | codes[i] = p->codes[i] ? I : N; | |
339 | } | |
340 | break; | |
341 | ||
342 | ||
343 | case MATCH_TEST: | |
344 | /* (match_test WHATEVER) is completely indeterminate. */ | |
345 | memset (codes, I, NUM_RTX_CODE); | |
346 | break; | |
347 | ||
348 | default: | |
bb933490 RS |
349 | error_with_line (pattern_lineno, |
350 | "'%s' cannot be used in a define_predicate expression", | |
351 | GET_RTX_NAME (GET_CODE (exp))); | |
e543e219 ZW |
352 | memset (codes, I, NUM_RTX_CODE); |
353 | break; | |
354 | } | |
355 | } | |
356 | ||
357 | #undef TRISTATE_OR | |
358 | #undef TRISTATE_AND | |
359 | #undef TRISTATE_NOT | |
360 | ||
361 | /* Process a define_predicate expression: compute the set of predicates | |
362 | that can be matched, and record this as a known predicate. */ | |
363 | static void | |
364 | process_define_predicate (rtx desc) | |
e0689256 | 365 | { |
7cbb2a85 | 366 | struct pred_data *pred = XCNEW (struct pred_data); |
e543e219 | 367 | char codes[NUM_RTX_CODE]; |
e543e219 | 368 | int i; |
e0689256 | 369 | |
e543e219 ZW |
370 | pred->name = XSTR (desc, 0); |
371 | if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE) | |
372 | pred->special = 1; | |
ec65fa66 | 373 | |
e543e219 | 374 | compute_predicate_codes (XEXP (desc, 1), codes); |
8fe0ca0c | 375 | |
e543e219 ZW |
376 | for (i = 0; i < NUM_RTX_CODE; i++) |
377 | if (codes[i] != N) | |
bbbbb16a | 378 | add_predicate_code (pred, (enum rtx_code) i); |
e663da80 | 379 | |
e543e219 ZW |
380 | add_predicate (pred); |
381 | } | |
382 | #undef I | |
383 | #undef N | |
384 | #undef Y | |
8fe0ca0c | 385 | |
e543e219 | 386 | \f |
09051660 | 387 | static struct decision *new_decision |
3d7aafde | 388 | (const char *, struct decision_head *); |
09051660 | 389 | static struct decision_test *new_decision_test |
3d7aafde | 390 | (enum decision_type, struct decision_test ***); |
8fe0ca0c | 391 | static rtx find_operand |
076963eb | 392 | (rtx, int, rtx); |
c0ea284b | 393 | static rtx find_matching_operand |
3d7aafde | 394 | (rtx, int); |
8fe0ca0c | 395 | static void validate_pattern |
3d7aafde | 396 | (rtx, rtx, rtx, int); |
09051660 | 397 | static struct decision *add_to_sequence |
3d7aafde | 398 | (rtx, struct decision_head *, const char *, enum routine_type, int); |
09051660 RH |
399 | |
400 | static int maybe_both_true_2 | |
3d7aafde | 401 | (struct decision_test *, struct decision_test *); |
09051660 | 402 | static int maybe_both_true_1 |
3d7aafde | 403 | (struct decision_test *, struct decision_test *); |
09051660 | 404 | static int maybe_both_true |
3d7aafde | 405 | (struct decision *, struct decision *, int); |
09051660 RH |
406 | |
407 | static int nodes_identical_1 | |
3d7aafde | 408 | (struct decision_test *, struct decision_test *); |
09051660 | 409 | static int nodes_identical |
3d7aafde | 410 | (struct decision *, struct decision *); |
09051660 | 411 | static void merge_accept_insn |
3d7aafde | 412 | (struct decision *, struct decision *); |
09051660 | 413 | static void merge_trees |
3d7aafde | 414 | (struct decision_head *, struct decision_head *); |
09051660 RH |
415 | |
416 | static void factor_tests | |
3d7aafde | 417 | (struct decision_head *); |
09051660 | 418 | static void simplify_tests |
3d7aafde | 419 | (struct decision_head *); |
09051660 | 420 | static int break_out_subroutines |
3d7aafde | 421 | (struct decision_head *, int); |
09051660 | 422 | static void find_afterward |
3d7aafde | 423 | (struct decision_head *, struct decision *); |
09051660 RH |
424 | |
425 | static void change_state | |
0cd6c85a | 426 | (const char *, const char *, const char *); |
09051660 | 427 | static void print_code |
3d7aafde | 428 | (enum rtx_code); |
09051660 | 429 | static void write_afterward |
3d7aafde | 430 | (struct decision *, struct decision *, const char *); |
09051660 | 431 | static struct decision *write_switch |
3d7aafde | 432 | (struct decision *, int); |
09051660 | 433 | static void write_cond |
3d7aafde | 434 | (struct decision_test *, int, enum routine_type); |
09051660 | 435 | static void write_action |
3d7aafde AJ |
436 | (struct decision *, struct decision_test *, int, int, |
437 | struct decision *, enum routine_type); | |
09051660 | 438 | static int is_unconditional |
3d7aafde | 439 | (struct decision_test *, enum routine_type); |
09051660 | 440 | static int write_node |
3d7aafde | 441 | (struct decision *, int, enum routine_type); |
09051660 | 442 | static void write_tree_1 |
3d7aafde | 443 | (struct decision_head *, int, enum routine_type); |
09051660 | 444 | static void write_tree |
3d7aafde | 445 | (struct decision_head *, const char *, enum routine_type, int); |
09051660 | 446 | static void write_subroutine |
3d7aafde | 447 | (struct decision_head *, enum routine_type); |
09051660 | 448 | static void write_subroutines |
3d7aafde | 449 | (struct decision_head *, enum routine_type); |
09051660 | 450 | static void write_header |
3d7aafde | 451 | (void); |
09051660 RH |
452 | |
453 | static struct decision_head make_insn_sequence | |
3d7aafde | 454 | (rtx, enum routine_type); |
09051660 | 455 | static void process_tree |
3d7aafde | 456 | (struct decision_head *, enum routine_type); |
5b7c7046 | 457 | |
36f0e0a6 | 458 | static void debug_decision_0 |
3d7aafde | 459 | (struct decision *, int, int); |
09051660 | 460 | static void debug_decision_1 |
3d7aafde | 461 | (struct decision *, int); |
09051660 | 462 | static void debug_decision_2 |
3d7aafde | 463 | (struct decision_test *); |
09051660 | 464 | extern void debug_decision |
3d7aafde | 465 | (struct decision *); |
36f0e0a6 | 466 | extern void debug_decision_list |
3d7aafde | 467 | (struct decision *); |
ede7cd44 | 468 | \f |
09051660 | 469 | /* Create a new node in sequence after LAST. */ |
e0689256 | 470 | |
09051660 | 471 | static struct decision * |
3d7aafde | 472 | new_decision (const char *position, struct decision_head *last) |
ec65fa66 | 473 | { |
8ad97cfc | 474 | struct decision *new_decision = XCNEW (struct decision); |
ec65fa66 | 475 | |
8ad97cfc KG |
476 | new_decision->success = *last; |
477 | new_decision->position = xstrdup (position); | |
478 | new_decision->number = next_number++; | |
ec65fa66 | 479 | |
8ad97cfc KG |
480 | last->first = last->last = new_decision; |
481 | return new_decision; | |
09051660 | 482 | } |
e0689256 | 483 | |
09051660 | 484 | /* Create a new test and link it in at PLACE. */ |
ec65fa66 | 485 | |
09051660 | 486 | static struct decision_test * |
3d7aafde | 487 | new_decision_test (enum decision_type type, struct decision_test ***pplace) |
09051660 RH |
488 | { |
489 | struct decision_test **place = *pplace; | |
490 | struct decision_test *test; | |
ec65fa66 | 491 | |
5ed6ace5 | 492 | test = XNEW (struct decision_test); |
09051660 RH |
493 | test->next = *place; |
494 | test->type = type; | |
495 | *place = test; | |
ede7cd44 | 496 | |
09051660 RH |
497 | place = &test->next; |
498 | *pplace = place; | |
ec65fa66 | 499 | |
09051660 | 500 | return test; |
e0689256 | 501 | } |
09051660 | 502 | |
076963eb | 503 | /* Search for and return operand N, stop when reaching node STOP. */ |
8fe0ca0c RH |
504 | |
505 | static rtx | |
076963eb | 506 | find_operand (rtx pattern, int n, rtx stop) |
8fe0ca0c RH |
507 | { |
508 | const char *fmt; | |
509 | RTX_CODE code; | |
510 | int i, j, len; | |
511 | rtx r; | |
512 | ||
076963eb JH |
513 | if (pattern == stop) |
514 | return stop; | |
515 | ||
8fe0ca0c RH |
516 | code = GET_CODE (pattern); |
517 | if ((code == MATCH_SCRATCH | |
8fe0ca0c RH |
518 | || code == MATCH_OPERAND |
519 | || code == MATCH_OPERATOR | |
520 | || code == MATCH_PARALLEL) | |
521 | && XINT (pattern, 0) == n) | |
522 | return pattern; | |
523 | ||
524 | fmt = GET_RTX_FORMAT (code); | |
525 | len = GET_RTX_LENGTH (code); | |
526 | for (i = 0; i < len; i++) | |
527 | { | |
528 | switch (fmt[i]) | |
529 | { | |
530 | case 'e': case 'u': | |
076963eb | 531 | if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX) |
8fe0ca0c RH |
532 | return r; |
533 | break; | |
534 | ||
c0ea284b RH |
535 | case 'V': |
536 | if (! XVEC (pattern, i)) | |
537 | break; | |
5d3cc252 | 538 | /* Fall through. */ |
c0ea284b | 539 | |
8fe0ca0c RH |
540 | case 'E': |
541 | for (j = 0; j < XVECLEN (pattern, i); j++) | |
076963eb JH |
542 | if ((r = find_operand (XVECEXP (pattern, i, j), n, stop)) |
543 | != NULL_RTX) | |
8fe0ca0c RH |
544 | return r; |
545 | break; | |
546 | ||
547 | case 'i': case 'w': case '0': case 's': | |
548 | break; | |
549 | ||
550 | default: | |
b2d59f6f | 551 | gcc_unreachable (); |
8fe0ca0c RH |
552 | } |
553 | } | |
554 | ||
555 | return NULL; | |
556 | } | |
557 | ||
c0ea284b RH |
558 | /* Search for and return operand M, such that it has a matching |
559 | constraint for operand N. */ | |
560 | ||
561 | static rtx | |
3d7aafde | 562 | find_matching_operand (rtx pattern, int n) |
c0ea284b RH |
563 | { |
564 | const char *fmt; | |
565 | RTX_CODE code; | |
566 | int i, j, len; | |
567 | rtx r; | |
568 | ||
569 | code = GET_CODE (pattern); | |
570 | if (code == MATCH_OPERAND | |
571 | && (XSTR (pattern, 2)[0] == '0' + n | |
572 | || (XSTR (pattern, 2)[0] == '%' | |
573 | && XSTR (pattern, 2)[1] == '0' + n))) | |
574 | return pattern; | |
575 | ||
576 | fmt = GET_RTX_FORMAT (code); | |
577 | len = GET_RTX_LENGTH (code); | |
578 | for (i = 0; i < len; i++) | |
579 | { | |
580 | switch (fmt[i]) | |
581 | { | |
582 | case 'e': case 'u': | |
583 | if ((r = find_matching_operand (XEXP (pattern, i), n))) | |
584 | return r; | |
585 | break; | |
586 | ||
587 | case 'V': | |
588 | if (! XVEC (pattern, i)) | |
589 | break; | |
5d3cc252 | 590 | /* Fall through. */ |
c0ea284b RH |
591 | |
592 | case 'E': | |
593 | for (j = 0; j < XVECLEN (pattern, i); j++) | |
594 | if ((r = find_matching_operand (XVECEXP (pattern, i, j), n))) | |
595 | return r; | |
596 | break; | |
597 | ||
598 | case 'i': case 'w': case '0': case 's': | |
599 | break; | |
600 | ||
601 | default: | |
b2d59f6f | 602 | gcc_unreachable (); |
c0ea284b RH |
603 | } |
604 | } | |
605 | ||
606 | return NULL; | |
607 | } | |
608 | ||
609 | ||
aece2740 | 610 | /* Check for various errors in patterns. SET is nonnull for a destination, |
7297e9fc RH |
611 | and is the complete set pattern. SET_CODE is '=' for normal sets, and |
612 | '+' within a context that requires in-out constraints. */ | |
bcdaba58 RH |
613 | |
614 | static void | |
3d7aafde | 615 | validate_pattern (rtx pattern, rtx insn, rtx set, int set_code) |
bcdaba58 RH |
616 | { |
617 | const char *fmt; | |
618 | RTX_CODE code; | |
8fe0ca0c RH |
619 | size_t i, len; |
620 | int j; | |
bcdaba58 RH |
621 | |
622 | code = GET_CODE (pattern); | |
623 | switch (code) | |
624 | { | |
625 | case MATCH_SCRATCH: | |
bcdaba58 | 626 | return; |
076963eb JH |
627 | case MATCH_DUP: |
628 | case MATCH_OP_DUP: | |
629 | case MATCH_PAR_DUP: | |
630 | if (find_operand (insn, XINT (pattern, 0), pattern) == pattern) | |
bb933490 RS |
631 | error_with_line (pattern_lineno, |
632 | "operand %i duplicated before defined", | |
633 | XINT (pattern, 0)); | |
076963eb | 634 | break; |
bcdaba58 | 635 | case MATCH_OPERAND: |
8fe0ca0c | 636 | case MATCH_OPERATOR: |
bcdaba58 RH |
637 | { |
638 | const char *pred_name = XSTR (pattern, 1); | |
e543e219 | 639 | const struct pred_data *pred; |
8fe0ca0c RH |
640 | const char *c_test; |
641 | ||
642 | if (GET_CODE (insn) == DEFINE_INSN) | |
643 | c_test = XSTR (insn, 2); | |
644 | else | |
645 | c_test = XSTR (insn, 1); | |
bcdaba58 RH |
646 | |
647 | if (pred_name[0] != 0) | |
648 | { | |
e543e219 ZW |
649 | pred = lookup_predicate (pred_name); |
650 | if (!pred) | |
651 | message_with_line (pattern_lineno, | |
652 | "warning: unknown predicate '%s'", | |
653 | pred_name); | |
8fe0ca0c | 654 | } |
e543e219 ZW |
655 | else |
656 | pred = 0; | |
8fe0ca0c | 657 | |
0dab343a | 658 | if (code == MATCH_OPERAND) |
aece2740 | 659 | { |
0dab343a RH |
660 | const char constraints0 = XSTR (pattern, 2)[0]; |
661 | ||
3d7aafde | 662 | /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we |
0dab343a RH |
663 | don't use the MATCH_OPERAND constraint, only the predicate. |
664 | This is confusing to folks doing new ports, so help them | |
665 | not make the mistake. */ | |
666 | if (GET_CODE (insn) == DEFINE_EXPAND | |
667 | || GET_CODE (insn) == DEFINE_SPLIT | |
668 | || GET_CODE (insn) == DEFINE_PEEPHOLE2) | |
7297e9fc | 669 | { |
0dab343a RH |
670 | if (constraints0) |
671 | message_with_line (pattern_lineno, | |
672 | "warning: constraints not supported in %s", | |
673 | rtx_name[GET_CODE (insn)]); | |
674 | } | |
3d7aafde | 675 | |
0dab343a RH |
676 | /* A MATCH_OPERAND that is a SET should have an output reload. */ |
677 | else if (set && constraints0) | |
678 | { | |
679 | if (set_code == '+') | |
680 | { | |
681 | if (constraints0 == '+') | |
682 | ; | |
683 | /* If we've only got an output reload for this operand, | |
684 | we'd better have a matching input operand. */ | |
685 | else if (constraints0 == '=' | |
686 | && find_matching_operand (insn, XINT (pattern, 0))) | |
687 | ; | |
688 | else | |
bb933490 RS |
689 | error_with_line (pattern_lineno, |
690 | "operand %d missing in-out reload", | |
c0ea284b | 691 | XINT (pattern, 0)); |
c0ea284b | 692 | } |
bb933490 RS |
693 | else if (constraints0 != '=' && constraints0 != '+') |
694 | error_with_line (pattern_lineno, | |
695 | "operand %d missing output reload", | |
696 | XINT (pattern, 0)); | |
7297e9fc | 697 | } |
aece2740 RH |
698 | } |
699 | ||
8fe0ca0c RH |
700 | /* Allowing non-lvalues in destinations -- particularly CONST_INT -- |
701 | while not likely to occur at runtime, results in less efficient | |
702 | code from insn-recog.c. */ | |
e543e219 ZW |
703 | if (set && pred && pred->allows_non_lvalue) |
704 | message_with_line (pattern_lineno, | |
705 | "warning: destination operand %d " | |
706 | "allows non-lvalue", | |
707 | XINT (pattern, 0)); | |
8fe0ca0c | 708 | |
e543e219 ZW |
709 | /* A modeless MATCH_OPERAND can be handy when we can check for |
710 | multiple modes in the c_test. In most other cases, it is a | |
711 | mistake. Only DEFINE_INSN is eligible, since SPLIT and | |
712 | PEEP2 can FAIL within the output pattern. Exclude special | |
713 | predicates, which check the mode themselves. Also exclude | |
714 | predicates that allow only constants. Exclude the SET_DEST | |
715 | of a call instruction, as that is a common idiom. */ | |
8fe0ca0c RH |
716 | |
717 | if (GET_MODE (pattern) == VOIDmode | |
718 | && code == MATCH_OPERAND | |
556ffcc5 | 719 | && GET_CODE (insn) == DEFINE_INSN |
e543e219 ZW |
720 | && pred |
721 | && !pred->special | |
722 | && pred->allows_non_const | |
aece2740 RH |
723 | && strstr (c_test, "operands") == NULL |
724 | && ! (set | |
725 | && GET_CODE (set) == SET | |
726 | && GET_CODE (SET_SRC (set)) == CALL)) | |
e543e219 ZW |
727 | message_with_line (pattern_lineno, |
728 | "warning: operand %d missing mode?", | |
729 | XINT (pattern, 0)); | |
bcdaba58 RH |
730 | return; |
731 | } | |
732 | ||
733 | case SET: | |
8fe0ca0c RH |
734 | { |
735 | enum machine_mode dmode, smode; | |
736 | rtx dest, src; | |
737 | ||
738 | dest = SET_DEST (pattern); | |
739 | src = SET_SRC (pattern); | |
740 | ||
0dab343a RH |
741 | /* STRICT_LOW_PART is a wrapper. Its argument is the real |
742 | destination, and it's mode should match the source. */ | |
743 | if (GET_CODE (dest) == STRICT_LOW_PART) | |
744 | dest = XEXP (dest, 0); | |
745 | ||
d91edf86 | 746 | /* Find the referent for a DUP. */ |
8fe0ca0c RH |
747 | |
748 | if (GET_CODE (dest) == MATCH_DUP | |
749 | || GET_CODE (dest) == MATCH_OP_DUP | |
750 | || GET_CODE (dest) == MATCH_PAR_DUP) | |
076963eb | 751 | dest = find_operand (insn, XINT (dest, 0), NULL); |
8fe0ca0c RH |
752 | |
753 | if (GET_CODE (src) == MATCH_DUP | |
754 | || GET_CODE (src) == MATCH_OP_DUP | |
755 | || GET_CODE (src) == MATCH_PAR_DUP) | |
076963eb | 756 | src = find_operand (insn, XINT (src, 0), NULL); |
8fe0ca0c | 757 | |
8fe0ca0c RH |
758 | dmode = GET_MODE (dest); |
759 | smode = GET_MODE (src); | |
bcdaba58 | 760 | |
8fe0ca0c RH |
761 | /* The mode of an ADDRESS_OPERAND is the mode of the memory |
762 | reference, not the mode of the address. */ | |
763 | if (GET_CODE (src) == MATCH_OPERAND | |
764 | && ! strcmp (XSTR (src, 1), "address_operand")) | |
765 | ; | |
766 | ||
767 | /* The operands of a SET must have the same mode unless one | |
768 | is VOIDmode. */ | |
769 | else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode) | |
bb933490 RS |
770 | error_with_line (pattern_lineno, |
771 | "mode mismatch in set: %smode vs %smode", | |
772 | GET_MODE_NAME (dmode), GET_MODE_NAME (smode)); | |
8fe0ca0c | 773 | |
5b7c7046 | 774 | /* If only one of the operands is VOIDmode, and PC or CC0 is |
8fe0ca0c RH |
775 | not involved, it's probably a mistake. */ |
776 | else if (dmode != smode | |
777 | && GET_CODE (dest) != PC | |
778 | && GET_CODE (dest) != CC0 | |
aece2740 RH |
779 | && GET_CODE (src) != PC |
780 | && GET_CODE (src) != CC0 | |
481683e1 | 781 | && !CONST_INT_P (src) |
23750d7f | 782 | && GET_CODE (src) != CALL) |
8fe0ca0c RH |
783 | { |
784 | const char *which; | |
785 | which = (dmode == VOIDmode ? "destination" : "source"); | |
786 | message_with_line (pattern_lineno, | |
787 | "warning: %s missing a mode?", which); | |
788 | } | |
789 | ||
790 | if (dest != SET_DEST (pattern)) | |
7297e9fc RH |
791 | validate_pattern (dest, insn, pattern, '='); |
792 | validate_pattern (SET_DEST (pattern), insn, pattern, '='); | |
793 | validate_pattern (SET_SRC (pattern), insn, NULL_RTX, 0); | |
8fe0ca0c RH |
794 | return; |
795 | } | |
796 | ||
797 | case CLOBBER: | |
7297e9fc RH |
798 | validate_pattern (SET_DEST (pattern), insn, pattern, '='); |
799 | return; | |
800 | ||
801 | case ZERO_EXTRACT: | |
802 | validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0); | |
803 | validate_pattern (XEXP (pattern, 1), insn, NULL_RTX, 0); | |
804 | validate_pattern (XEXP (pattern, 2), insn, NULL_RTX, 0); | |
805 | return; | |
806 | ||
807 | case STRICT_LOW_PART: | |
808 | validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0); | |
bcdaba58 | 809 | return; |
8fe0ca0c | 810 | |
bcdaba58 RH |
811 | case LABEL_REF: |
812 | if (GET_MODE (XEXP (pattern, 0)) != VOIDmode) | |
bb933490 RS |
813 | error_with_line (pattern_lineno, |
814 | "operand to label_ref %smode not VOIDmode", | |
815 | GET_MODE_NAME (GET_MODE (XEXP (pattern, 0)))); | |
bcdaba58 RH |
816 | break; |
817 | ||
818 | default: | |
819 | break; | |
820 | } | |
821 | ||
822 | fmt = GET_RTX_FORMAT (code); | |
823 | len = GET_RTX_LENGTH (code); | |
824 | for (i = 0; i < len; i++) | |
825 | { | |
826 | switch (fmt[i]) | |
827 | { | |
828 | case 'e': case 'u': | |
7297e9fc | 829 | validate_pattern (XEXP (pattern, i), insn, NULL_RTX, 0); |
bcdaba58 RH |
830 | break; |
831 | ||
832 | case 'E': | |
833 | for (j = 0; j < XVECLEN (pattern, i); j++) | |
7297e9fc | 834 | validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0); |
bcdaba58 RH |
835 | break; |
836 | ||
837 | case 'i': case 'w': case '0': case 's': | |
838 | break; | |
839 | ||
840 | default: | |
b2d59f6f | 841 | gcc_unreachable (); |
bcdaba58 RH |
842 | } |
843 | } | |
bcdaba58 RH |
844 | } |
845 | ||
e0689256 RK |
846 | /* Create a chain of nodes to verify that an rtl expression matches |
847 | PATTERN. | |
ec65fa66 | 848 | |
e0689256 RK |
849 | LAST is a pointer to the listhead in the previous node in the chain (or |
850 | in the calling function, for the first node). | |
ec65fa66 | 851 | |
e0689256 | 852 | POSITION is the string representing the current position in the insn. |
ec65fa66 | 853 | |
ede7cd44 RH |
854 | INSN_TYPE is the type of insn for which we are emitting code. |
855 | ||
e0689256 | 856 | A pointer to the final node in the chain is returned. */ |
ec65fa66 RK |
857 | |
858 | static struct decision * | |
3d7aafde AJ |
859 | add_to_sequence (rtx pattern, struct decision_head *last, const char *position, |
860 | enum routine_type insn_type, int top) | |
ec65fa66 | 861 | { |
09051660 | 862 | RTX_CODE code; |
8ad97cfc | 863 | struct decision *this_decision, *sub; |
09051660 RH |
864 | struct decision_test *test; |
865 | struct decision_test **place; | |
866 | char *subpos; | |
b3694847 SS |
867 | size_t i; |
868 | const char *fmt; | |
e0689256 | 869 | int depth = strlen (position); |
ec65fa66 | 870 | int len; |
09051660 | 871 | enum machine_mode mode; |
ec65fa66 | 872 | |
e0689256 RK |
873 | if (depth > max_depth) |
874 | max_depth = depth; | |
875 | ||
7cbb2a85 | 876 | subpos = XNEWVAR (char, depth + 2); |
09051660 RH |
877 | strcpy (subpos, position); |
878 | subpos[depth + 1] = 0; | |
ec65fa66 | 879 | |
8ad97cfc KG |
880 | sub = this_decision = new_decision (position, last); |
881 | place = &this_decision->tests; | |
ec65fa66 RK |
882 | |
883 | restart: | |
09051660 RH |
884 | mode = GET_MODE (pattern); |
885 | code = GET_CODE (pattern); | |
ec65fa66 RK |
886 | |
887 | switch (code) | |
888 | { | |
ede7cd44 | 889 | case PARALLEL: |
dc297297 | 890 | /* Toplevel peephole pattern. */ |
ede7cd44 RH |
891 | if (insn_type == PEEPHOLE2 && top) |
892 | { | |
0cd6c85a PB |
893 | int num_insns; |
894 | ||
895 | /* Check we have sufficient insns. This avoids complications | |
896 | because we then know peep2_next_insn never fails. */ | |
897 | num_insns = XVECLEN (pattern, 0); | |
898 | if (num_insns > 1) | |
899 | { | |
900 | test = new_decision_test (DT_num_insns, &place); | |
901 | test->u.num_insns = num_insns; | |
902 | last = &sub->success; | |
903 | } | |
904 | else | |
905 | { | |
906 | /* We don't need the node we just created -- unlink it. */ | |
907 | last->first = last->last = NULL; | |
908 | } | |
ede7cd44 RH |
909 | |
910 | for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++) | |
911 | { | |
912 | /* Which insn we're looking at is represented by A-Z. We don't | |
dc297297 | 913 | ever use 'A', however; it is always implied. */ |
09051660 RH |
914 | |
915 | subpos[depth] = (i > 0 ? 'A' + i : 0); | |
916 | sub = add_to_sequence (XVECEXP (pattern, 0, i), | |
917 | last, subpos, insn_type, 0); | |
918 | last = &sub->success; | |
ede7cd44 | 919 | } |
b548dffb | 920 | goto ret; |
ede7cd44 | 921 | } |
09051660 RH |
922 | |
923 | /* Else nothing special. */ | |
ede7cd44 | 924 | break; |
09051660 | 925 | |
521b9224 RH |
926 | case MATCH_PARALLEL: |
927 | /* The explicit patterns within a match_parallel enforce a minimum | |
928 | length on the vector. The match_parallel predicate may allow | |
929 | for more elements. We do need to check for this minimum here | |
930 | or the code generated to match the internals may reference data | |
931 | beyond the end of the vector. */ | |
932 | test = new_decision_test (DT_veclen_ge, &place); | |
933 | test->u.veclen = XVECLEN (pattern, 2); | |
5d3cc252 | 934 | /* Fall through. */ |
521b9224 | 935 | |
ec65fa66 | 936 | case MATCH_OPERAND: |
ec65fa66 | 937 | case MATCH_SCRATCH: |
ec65fa66 | 938 | case MATCH_OPERATOR: |
09051660 | 939 | { |
09051660 | 940 | RTX_CODE was_code = code; |
e543e219 ZW |
941 | const char *pred_name; |
942 | bool allows_const_int = true; | |
09051660 RH |
943 | |
944 | if (code == MATCH_SCRATCH) | |
945 | { | |
946 | pred_name = "scratch_operand"; | |
947 | code = UNKNOWN; | |
948 | } | |
949 | else | |
950 | { | |
951 | pred_name = XSTR (pattern, 1); | |
952 | if (code == MATCH_PARALLEL) | |
953 | code = PARALLEL; | |
954 | else | |
955 | code = UNKNOWN; | |
956 | } | |
957 | ||
29360e56 | 958 | if (pred_name[0] != 0) |
09051660 | 959 | { |
e543e219 ZW |
960 | const struct pred_data *pred; |
961 | ||
09051660 RH |
962 | test = new_decision_test (DT_pred, &place); |
963 | test->u.pred.name = pred_name; | |
964 | test->u.pred.mode = mode; | |
965 | ||
e543e219 ZW |
966 | /* See if we know about this predicate. |
967 | If we do, remember it for use below. | |
e0689256 | 968 | |
e543e219 ZW |
969 | We can optimize the generated code a little if either |
970 | (a) the predicate only accepts one code, or (b) the | |
971 | predicate does not allow CONST_INT, in which case it | |
972 | can match only if the modes match. */ | |
973 | pred = lookup_predicate (pred_name); | |
974 | if (pred) | |
9edd4689 | 975 | { |
e543e219 ZW |
976 | test->u.pred.data = pred; |
977 | allows_const_int = pred->codes[CONST_INT]; | |
47d2cee5 ZW |
978 | if (was_code == MATCH_PARALLEL |
979 | && pred->singleton != PARALLEL) | |
980 | message_with_line (pattern_lineno, | |
981 | "predicate '%s' used in match_parallel " | |
982 | "does not allow only PARALLEL", pred->name); | |
983 | else | |
984 | code = pred->singleton; | |
9edd4689 | 985 | } |
47d2cee5 ZW |
986 | else |
987 | message_with_line (pattern_lineno, | |
988 | "warning: unknown predicate '%s' in '%s' expression", | |
989 | pred_name, GET_RTX_NAME (was_code)); | |
09051660 | 990 | } |
ec1c89e6 RH |
991 | |
992 | /* Can't enforce a mode if we allow const_int. */ | |
993 | if (allows_const_int) | |
994 | mode = VOIDmode; | |
e0689256 | 995 | |
89dbed81 | 996 | /* Accept the operand, i.e. record it in `operands'. */ |
09051660 RH |
997 | test = new_decision_test (DT_accept_op, &place); |
998 | test->u.opno = XINT (pattern, 0); | |
e0689256 | 999 | |
09051660 RH |
1000 | if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL) |
1001 | { | |
1002 | char base = (was_code == MATCH_OPERATOR ? '0' : 'a'); | |
1003 | for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++) | |
1004 | { | |
1005 | subpos[depth] = i + base; | |
1006 | sub = add_to_sequence (XVECEXP (pattern, 2, i), | |
1007 | &sub->success, subpos, insn_type, 0); | |
1008 | } | |
1009 | } | |
1010 | goto fini; | |
1011 | } | |
ec65fa66 RK |
1012 | |
1013 | case MATCH_OP_DUP: | |
09051660 RH |
1014 | code = UNKNOWN; |
1015 | ||
1016 | test = new_decision_test (DT_dup, &place); | |
1017 | test->u.dup = XINT (pattern, 0); | |
1018 | ||
1019 | test = new_decision_test (DT_accept_op, &place); | |
1020 | test->u.opno = XINT (pattern, 0); | |
1021 | ||
e51712db | 1022 | for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++) |
ec65fa66 | 1023 | { |
09051660 RH |
1024 | subpos[depth] = i + '0'; |
1025 | sub = add_to_sequence (XVECEXP (pattern, 1, i), | |
1026 | &sub->success, subpos, insn_type, 0); | |
ec65fa66 | 1027 | } |
09051660 | 1028 | goto fini; |
ec65fa66 RK |
1029 | |
1030 | case MATCH_DUP: | |
f582c9d5 | 1031 | case MATCH_PAR_DUP: |
09051660 RH |
1032 | code = UNKNOWN; |
1033 | ||
1034 | test = new_decision_test (DT_dup, &place); | |
1035 | test->u.dup = XINT (pattern, 0); | |
1036 | goto fini; | |
ec65fa66 RK |
1037 | |
1038 | case ADDRESS: | |
1039 | pattern = XEXP (pattern, 0); | |
1040 | goto restart; | |
1041 | ||
76d31c63 JL |
1042 | default: |
1043 | break; | |
ec65fa66 RK |
1044 | } |
1045 | ||
1046 | fmt = GET_RTX_FORMAT (code); | |
1047 | len = GET_RTX_LENGTH (code); | |
09051660 RH |
1048 | |
1049 | /* Do tests against the current node first. */ | |
e51712db | 1050 | for (i = 0; i < (size_t) len; i++) |
ec65fa66 | 1051 | { |
09051660 | 1052 | if (fmt[i] == 'i') |
ec65fa66 | 1053 | { |
b2d59f6f | 1054 | gcc_assert (i < 2); |
5abc5de9 | 1055 | |
b2d59f6f | 1056 | if (!i) |
09051660 RH |
1057 | { |
1058 | test = new_decision_test (DT_elt_zero_int, &place); | |
1059 | test->u.intval = XINT (pattern, i); | |
1060 | } | |
b2d59f6f | 1061 | else |
09051660 RH |
1062 | { |
1063 | test = new_decision_test (DT_elt_one_int, &place); | |
1064 | test->u.intval = XINT (pattern, i); | |
1065 | } | |
ec65fa66 | 1066 | } |
09051660 | 1067 | else if (fmt[i] == 'w') |
3d678dca | 1068 | { |
070ef6f4 RK |
1069 | /* If this value actually fits in an int, we can use a switch |
1070 | statement here, so indicate that. */ | |
1071 | enum decision_type type | |
1072 | = ((int) XWINT (pattern, i) == XWINT (pattern, i)) | |
1073 | ? DT_elt_zero_wide_safe : DT_elt_zero_wide; | |
1074 | ||
b2d59f6f | 1075 | gcc_assert (!i); |
09051660 | 1076 | |
070ef6f4 | 1077 | test = new_decision_test (type, &place); |
09051660 | 1078 | test->u.intval = XWINT (pattern, i); |
3d678dca | 1079 | } |
ec65fa66 RK |
1080 | else if (fmt[i] == 'E') |
1081 | { | |
b2d59f6f | 1082 | gcc_assert (!i); |
09051660 RH |
1083 | |
1084 | test = new_decision_test (DT_veclen, &place); | |
1085 | test->u.veclen = XVECLEN (pattern, i); | |
1086 | } | |
1087 | } | |
1088 | ||
1089 | /* Now test our sub-patterns. */ | |
1090 | for (i = 0; i < (size_t) len; i++) | |
1091 | { | |
1092 | switch (fmt[i]) | |
1093 | { | |
1094 | case 'e': case 'u': | |
1095 | subpos[depth] = '0' + i; | |
1096 | sub = add_to_sequence (XEXP (pattern, i), &sub->success, | |
1097 | subpos, insn_type, 0); | |
1098 | break; | |
1099 | ||
1100 | case 'E': | |
1101 | { | |
b3694847 | 1102 | int j; |
09051660 RH |
1103 | for (j = 0; j < XVECLEN (pattern, i); j++) |
1104 | { | |
1105 | subpos[depth] = 'a' + j; | |
1106 | sub = add_to_sequence (XVECEXP (pattern, i, j), | |
1107 | &sub->success, subpos, insn_type, 0); | |
1108 | } | |
1109 | break; | |
1110 | } | |
1111 | ||
1112 | case 'i': case 'w': | |
1113 | /* Handled above. */ | |
1114 | break; | |
1115 | case '0': | |
1116 | break; | |
1117 | ||
1118 | default: | |
b2d59f6f | 1119 | gcc_unreachable (); |
09051660 RH |
1120 | } |
1121 | } | |
1122 | ||
1123 | fini: | |
1124 | /* Insert nodes testing mode and code, if they're still relevant, | |
1125 | before any of the nodes we may have added above. */ | |
1126 | if (code != UNKNOWN) | |
1127 | { | |
8ad97cfc | 1128 | place = &this_decision->tests; |
09051660 RH |
1129 | test = new_decision_test (DT_code, &place); |
1130 | test->u.code = code; | |
1131 | } | |
1132 | ||
1133 | if (mode != VOIDmode) | |
1134 | { | |
8ad97cfc | 1135 | place = &this_decision->tests; |
09051660 RH |
1136 | test = new_decision_test (DT_mode, &place); |
1137 | test->u.mode = mode; | |
1138 | } | |
1139 | ||
1140 | /* If we didn't insert any tests or accept nodes, hork. */ | |
8ad97cfc | 1141 | gcc_assert (this_decision->tests); |
09051660 | 1142 | |
b548dffb ZW |
1143 | ret: |
1144 | free (subpos); | |
09051660 RH |
1145 | return sub; |
1146 | } | |
1147 | \f | |
1148 | /* A subroutine of maybe_both_true; examines only one test. | |
1149 | Returns > 0 for "definitely both true" and < 0 for "maybe both true". */ | |
1150 | ||
1151 | static int | |
3d7aafde | 1152 | maybe_both_true_2 (struct decision_test *d1, struct decision_test *d2) |
09051660 RH |
1153 | { |
1154 | if (d1->type == d2->type) | |
1155 | { | |
1156 | switch (d1->type) | |
1157 | { | |
0cd6c85a PB |
1158 | case DT_num_insns: |
1159 | if (d1->u.num_insns == d2->u.num_insns) | |
1160 | return 1; | |
1161 | else | |
1162 | return -1; | |
1163 | ||
09051660 | 1164 | case DT_mode: |
f0e1f482 | 1165 | return d1->u.mode == d2->u.mode; |
09051660 RH |
1166 | |
1167 | case DT_code: | |
1168 | return d1->u.code == d2->u.code; | |
1169 | ||
1170 | case DT_veclen: | |
1171 | return d1->u.veclen == d2->u.veclen; | |
1172 | ||
1173 | case DT_elt_zero_int: | |
1174 | case DT_elt_one_int: | |
1175 | case DT_elt_zero_wide: | |
070ef6f4 | 1176 | case DT_elt_zero_wide_safe: |
09051660 RH |
1177 | return d1->u.intval == d2->u.intval; |
1178 | ||
1179 | default: | |
1180 | break; | |
1181 | } | |
1182 | } | |
1183 | ||
1184 | /* If either has a predicate that we know something about, set | |
1185 | things up so that D1 is the one that always has a known | |
1186 | predicate. Then see if they have any codes in common. */ | |
1187 | ||
1188 | if (d1->type == DT_pred || d2->type == DT_pred) | |
1189 | { | |
1190 | if (d2->type == DT_pred) | |
1191 | { | |
1192 | struct decision_test *tmp; | |
1193 | tmp = d1, d1 = d2, d2 = tmp; | |
1194 | } | |
1195 | ||
1196 | /* If D2 tests a mode, see if it matches D1. */ | |
1197 | if (d1->u.pred.mode != VOIDmode) | |
1198 | { | |
1199 | if (d2->type == DT_mode) | |
1200 | { | |
f0e1f482 | 1201 | if (d1->u.pred.mode != d2->u.mode |
8f496bc2 HPN |
1202 | /* The mode of an address_operand predicate is the |
1203 | mode of the memory, not the operand. It can only | |
1204 | be used for testing the predicate, so we must | |
1205 | ignore it here. */ | |
1206 | && strcmp (d1->u.pred.name, "address_operand") != 0) | |
09051660 RH |
1207 | return 0; |
1208 | } | |
4dc320a5 RH |
1209 | /* Don't check two predicate modes here, because if both predicates |
1210 | accept CONST_INT, then both can still be true even if the modes | |
1211 | are different. If they don't accept CONST_INT, there will be a | |
1212 | separate DT_mode that will make maybe_both_true_1 return 0. */ | |
09051660 RH |
1213 | } |
1214 | ||
e543e219 | 1215 | if (d1->u.pred.data) |
09051660 RH |
1216 | { |
1217 | /* If D2 tests a code, see if it is in the list of valid | |
1218 | codes for D1's predicate. */ | |
1219 | if (d2->type == DT_code) | |
1220 | { | |
e543e219 | 1221 | if (!d1->u.pred.data->codes[d2->u.code]) |
09051660 RH |
1222 | return 0; |
1223 | } | |
1224 | ||
1225 | /* Otherwise see if the predicates have any codes in common. */ | |
e543e219 | 1226 | else if (d2->type == DT_pred && d2->u.pred.data) |
ec65fa66 | 1227 | { |
e543e219 | 1228 | bool common = false; |
32e8bb8e | 1229 | int c; |
09051660 | 1230 | |
e543e219 ZW |
1231 | for (c = 0; c < NUM_RTX_CODE; c++) |
1232 | if (d1->u.pred.data->codes[c] && d2->u.pred.data->codes[c]) | |
1233 | { | |
1234 | common = true; | |
1235 | break; | |
1236 | } | |
09051660 RH |
1237 | |
1238 | if (!common) | |
1239 | return 0; | |
ec65fa66 RK |
1240 | } |
1241 | } | |
ec65fa66 | 1242 | } |
09051660 | 1243 | |
521b9224 RH |
1244 | /* Tests vs veclen may be known when strict equality is involved. */ |
1245 | if (d1->type == DT_veclen && d2->type == DT_veclen_ge) | |
1246 | return d1->u.veclen >= d2->u.veclen; | |
1247 | if (d1->type == DT_veclen_ge && d2->type == DT_veclen) | |
1248 | return d2->u.veclen >= d1->u.veclen; | |
1249 | ||
09051660 | 1250 | return -1; |
ec65fa66 | 1251 | } |
09051660 RH |
1252 | |
1253 | /* A subroutine of maybe_both_true; examines all the tests for a given node. | |
1254 | Returns > 0 for "definitely both true" and < 0 for "maybe both true". */ | |
1255 | ||
1256 | static int | |
3d7aafde | 1257 | maybe_both_true_1 (struct decision_test *d1, struct decision_test *d2) |
09051660 RH |
1258 | { |
1259 | struct decision_test *t1, *t2; | |
1260 | ||
1261 | /* A match_operand with no predicate can match anything. Recognize | |
ff7cc307 | 1262 | this by the existence of a lone DT_accept_op test. */ |
09051660 RH |
1263 | if (d1->type == DT_accept_op || d2->type == DT_accept_op) |
1264 | return 1; | |
1265 | ||
1266 | /* Eliminate pairs of tests while they can exactly match. */ | |
1267 | while (d1 && d2 && d1->type == d2->type) | |
1268 | { | |
1269 | if (maybe_both_true_2 (d1, d2) == 0) | |
1270 | return 0; | |
1271 | d1 = d1->next, d2 = d2->next; | |
1272 | } | |
1273 | ||
1274 | /* After that, consider all pairs. */ | |
1275 | for (t1 = d1; t1 ; t1 = t1->next) | |
1276 | for (t2 = d2; t2 ; t2 = t2->next) | |
1277 | if (maybe_both_true_2 (t1, t2) == 0) | |
1278 | return 0; | |
1279 | ||
1280 | return -1; | |
1281 | } | |
1282 | ||
1283 | /* Return 0 if we can prove that there is no RTL that can match both | |
1284 | D1 and D2. Otherwise, return 1 (it may be that there is an RTL that | |
e0689256 | 1285 | can match both or just that we couldn't prove there wasn't such an RTL). |
ec65fa66 | 1286 | |
cc2902df | 1287 | TOPLEVEL is nonzero if we are to only look at the top level and not |
e0689256 | 1288 | recursively descend. */ |
ec65fa66 | 1289 | |
e0689256 | 1290 | static int |
3d7aafde AJ |
1291 | maybe_both_true (struct decision *d1, struct decision *d2, |
1292 | int toplevel) | |
ec65fa66 | 1293 | { |
e0689256 | 1294 | struct decision *p1, *p2; |
00ec6daa JH |
1295 | int cmp; |
1296 | ||
1297 | /* Don't compare strings on the different positions in insn. Doing so | |
1298 | is incorrect and results in false matches from constructs like | |
1299 | ||
1300 | [(set (subreg:HI (match_operand:SI "register_operand" "r") 0) | |
1301 | (subreg:HI (match_operand:SI "register_operand" "r") 0))] | |
1302 | vs | |
1303 | [(set (match_operand:HI "register_operand" "r") | |
1304 | (match_operand:HI "register_operand" "r"))] | |
1305 | ||
1306 | If we are presented with such, we are recursing through the remainder | |
1307 | of a node's success nodes (from the loop at the end of this function). | |
1308 | Skip forward until we come to a position that matches. | |
1309 | ||
1310 | Due to the way position strings are constructed, we know that iterating | |
1311 | forward from the lexically lower position (e.g. "00") will run into | |
1312 | the lexically higher position (e.g. "1") and not the other way around. | |
1313 | This saves a bit of effort. */ | |
1314 | ||
1315 | cmp = strcmp (d1->position, d2->position); | |
1316 | if (cmp != 0) | |
1317 | { | |
b2d59f6f | 1318 | gcc_assert (!toplevel); |
00ec6daa JH |
1319 | |
1320 | /* If the d2->position was lexically lower, swap. */ | |
1321 | if (cmp > 0) | |
ace91ff1 | 1322 | p1 = d1, d1 = d2, d2 = p1; |
00ec6daa JH |
1323 | |
1324 | if (d1->success.first == 0) | |
29360e56 | 1325 | return 1; |
00ec6daa | 1326 | for (p1 = d1->success.first; p1; p1 = p1->next) |
09051660 RH |
1327 | if (maybe_both_true (p1, d2, 0)) |
1328 | return 1; | |
00ec6daa | 1329 | |
09051660 | 1330 | return 0; |
00ec6daa | 1331 | } |
e0689256 | 1332 | |
09051660 RH |
1333 | /* Test the current level. */ |
1334 | cmp = maybe_both_true_1 (d1->tests, d2->tests); | |
1335 | if (cmp >= 0) | |
1336 | return cmp; | |
1337 | ||
1338 | /* We can't prove that D1 and D2 cannot both be true. If we are only | |
1339 | to check the top level, return 1. Otherwise, see if we can prove | |
1340 | that all choices in both successors are mutually exclusive. If | |
1341 | either does not have any successors, we can't prove they can't both | |
1342 | be true. */ | |
1343 | ||
1344 | if (toplevel || d1->success.first == 0 || d2->success.first == 0) | |
e0689256 RK |
1345 | return 1; |
1346 | ||
09051660 RH |
1347 | for (p1 = d1->success.first; p1; p1 = p1->next) |
1348 | for (p2 = d2->success.first; p2; p2 = p2->next) | |
1349 | if (maybe_both_true (p1, p2, 0)) | |
1350 | return 1; | |
e0689256 | 1351 | |
09051660 RH |
1352 | return 0; |
1353 | } | |
ec65fa66 | 1354 | |
09051660 | 1355 | /* A subroutine of nodes_identical. Examine two tests for equivalence. */ |
ec65fa66 | 1356 | |
09051660 | 1357 | static int |
3d7aafde | 1358 | nodes_identical_1 (struct decision_test *d1, struct decision_test *d2) |
09051660 RH |
1359 | { |
1360 | switch (d1->type) | |
ec65fa66 | 1361 | { |
0cd6c85a PB |
1362 | case DT_num_insns: |
1363 | return d1->u.num_insns == d2->u.num_insns; | |
1364 | ||
09051660 RH |
1365 | case DT_mode: |
1366 | return d1->u.mode == d2->u.mode; | |
e0689256 | 1367 | |
09051660 RH |
1368 | case DT_code: |
1369 | return d1->u.code == d2->u.code; | |
e0689256 | 1370 | |
09051660 RH |
1371 | case DT_pred: |
1372 | return (d1->u.pred.mode == d2->u.pred.mode | |
1373 | && strcmp (d1->u.pred.name, d2->u.pred.name) == 0); | |
e0689256 | 1374 | |
09051660 RH |
1375 | case DT_c_test: |
1376 | return strcmp (d1->u.c_test, d2->u.c_test) == 0; | |
e0689256 | 1377 | |
09051660 | 1378 | case DT_veclen: |
521b9224 | 1379 | case DT_veclen_ge: |
09051660 | 1380 | return d1->u.veclen == d2->u.veclen; |
e0689256 | 1381 | |
09051660 RH |
1382 | case DT_dup: |
1383 | return d1->u.dup == d2->u.dup; | |
e0689256 | 1384 | |
09051660 RH |
1385 | case DT_elt_zero_int: |
1386 | case DT_elt_one_int: | |
1387 | case DT_elt_zero_wide: | |
070ef6f4 | 1388 | case DT_elt_zero_wide_safe: |
09051660 | 1389 | return d1->u.intval == d2->u.intval; |
e0689256 | 1390 | |
09051660 RH |
1391 | case DT_accept_op: |
1392 | return d1->u.opno == d2->u.opno; | |
1393 | ||
1394 | case DT_accept_insn: | |
1395 | /* Differences will be handled in merge_accept_insn. */ | |
1396 | return 1; | |
1397 | ||
1398 | default: | |
b2d59f6f | 1399 | gcc_unreachable (); |
ec65fa66 | 1400 | } |
09051660 | 1401 | } |
ec65fa66 | 1402 | |
09051660 | 1403 | /* True iff the two nodes are identical (on one level only). Due |
5b7c7046 | 1404 | to the way these lists are constructed, we shouldn't have to |
09051660 | 1405 | consider different orderings on the tests. */ |
ec65fa66 | 1406 | |
09051660 | 1407 | static int |
3d7aafde | 1408 | nodes_identical (struct decision *d1, struct decision *d2) |
09051660 RH |
1409 | { |
1410 | struct decision_test *t1, *t2; | |
e0689256 | 1411 | |
09051660 RH |
1412 | for (t1 = d1->tests, t2 = d2->tests; t1 && t2; t1 = t1->next, t2 = t2->next) |
1413 | { | |
1414 | if (t1->type != t2->type) | |
1415 | return 0; | |
1416 | if (! nodes_identical_1 (t1, t2)) | |
e0689256 | 1417 | return 0; |
09051660 | 1418 | } |
e0689256 | 1419 | |
09051660 | 1420 | /* For success, they should now both be null. */ |
aece2740 RH |
1421 | if (t1 != t2) |
1422 | return 0; | |
1423 | ||
1424 | /* Check that their subnodes are at the same position, as any one set | |
2cec75a1 RH |
1425 | of sibling decisions must be at the same position. Allowing this |
1426 | requires complications to find_afterward and when change_state is | |
1427 | invoked. */ | |
aece2740 RH |
1428 | if (d1->success.first |
1429 | && d2->success.first | |
1430 | && strcmp (d1->success.first->position, d2->success.first->position)) | |
1431 | return 0; | |
1432 | ||
1433 | return 1; | |
e0689256 | 1434 | } |
e0689256 | 1435 | |
09051660 RH |
1436 | /* A subroutine of merge_trees; given two nodes that have been declared |
1437 | identical, cope with two insn accept states. If they differ in the | |
1438 | number of clobbers, then the conflict was created by make_insn_sequence | |
5b7c7046 | 1439 | and we can drop the with-clobbers version on the floor. If both |
09051660 RH |
1440 | nodes have no additional clobbers, we have found an ambiguity in the |
1441 | source machine description. */ | |
1442 | ||
1443 | static void | |
3d7aafde | 1444 | merge_accept_insn (struct decision *oldd, struct decision *addd) |
ec65fa66 | 1445 | { |
09051660 RH |
1446 | struct decision_test *old, *add; |
1447 | ||
1448 | for (old = oldd->tests; old; old = old->next) | |
1449 | if (old->type == DT_accept_insn) | |
1450 | break; | |
1451 | if (old == NULL) | |
1452 | return; | |
e0689256 | 1453 | |
09051660 RH |
1454 | for (add = addd->tests; add; add = add->next) |
1455 | if (add->type == DT_accept_insn) | |
1456 | break; | |
1457 | if (add == NULL) | |
1458 | return; | |
e0689256 | 1459 | |
09051660 RH |
1460 | /* If one node is for a normal insn and the second is for the base |
1461 | insn with clobbers stripped off, the second node should be ignored. */ | |
e0689256 | 1462 | |
09051660 RH |
1463 | if (old->u.insn.num_clobbers_to_add == 0 |
1464 | && add->u.insn.num_clobbers_to_add > 0) | |
1465 | { | |
1466 | /* Nothing to do here. */ | |
1467 | } | |
1468 | else if (old->u.insn.num_clobbers_to_add > 0 | |
1469 | && add->u.insn.num_clobbers_to_add == 0) | |
1470 | { | |
1471 | /* In this case, replace OLD with ADD. */ | |
1472 | old->u.insn = add->u.insn; | |
1473 | } | |
1474 | else | |
1475 | { | |
bb933490 RS |
1476 | error_with_line (add->u.insn.lineno, "`%s' matches `%s'", |
1477 | get_insn_name (add->u.insn.code_number), | |
1478 | get_insn_name (old->u.insn.code_number)); | |
bcdaba58 RH |
1479 | message_with_line (old->u.insn.lineno, "previous definition of `%s'", |
1480 | get_insn_name (old->u.insn.code_number)); | |
09051660 | 1481 | } |
e0689256 | 1482 | } |
e0689256 | 1483 | |
09051660 RH |
1484 | /* Merge two decision trees OLDH and ADDH, modifying OLDH destructively. */ |
1485 | ||
1486 | static void | |
3d7aafde | 1487 | merge_trees (struct decision_head *oldh, struct decision_head *addh) |
e0689256 | 1488 | { |
09051660 | 1489 | struct decision *next, *add; |
e0689256 | 1490 | |
09051660 RH |
1491 | if (addh->first == 0) |
1492 | return; | |
1493 | if (oldh->first == 0) | |
1494 | { | |
1495 | *oldh = *addh; | |
1496 | return; | |
1497 | } | |
ec65fa66 | 1498 | |
09051660 | 1499 | /* Trying to merge bits at different positions isn't possible. */ |
b2d59f6f | 1500 | gcc_assert (!strcmp (oldh->first->position, addh->first->position)); |
e0689256 | 1501 | |
09051660 | 1502 | for (add = addh->first; add ; add = next) |
ec65fa66 | 1503 | { |
09051660 | 1504 | struct decision *old, *insert_before = NULL; |
e0689256 RK |
1505 | |
1506 | next = add->next; | |
1507 | ||
09051660 RH |
1508 | /* The semantics of pattern matching state that the tests are |
1509 | done in the order given in the MD file so that if an insn | |
1510 | matches two patterns, the first one will be used. However, | |
1511 | in practice, most, if not all, patterns are unambiguous so | |
1512 | that their order is independent. In that case, we can merge | |
1513 | identical tests and group all similar modes and codes together. | |
e0689256 RK |
1514 | |
1515 | Scan starting from the end of OLDH until we reach a point | |
09051660 RH |
1516 | where we reach the head of the list or where we pass a |
1517 | pattern that could also be true if NEW is true. If we find | |
1518 | an identical pattern, we can merge them. Also, record the | |
1519 | last node that tests the same code and mode and the last one | |
1520 | that tests just the same mode. | |
e0689256 RK |
1521 | |
1522 | If we have no match, place NEW after the closest match we found. */ | |
5b7c7046 | 1523 | |
09051660 | 1524 | for (old = oldh->last; old; old = old->prev) |
ec65fa66 | 1525 | { |
09051660 | 1526 | if (nodes_identical (old, add)) |
e0689256 | 1527 | { |
09051660 RH |
1528 | merge_accept_insn (old, add); |
1529 | merge_trees (&old->success, &add->success); | |
1530 | goto merged_nodes; | |
1531 | } | |
e0689256 | 1532 | |
09051660 RH |
1533 | if (maybe_both_true (old, add, 0)) |
1534 | break; | |
e0689256 | 1535 | |
09051660 RH |
1536 | /* Insert the nodes in DT test type order, which is roughly |
1537 | how expensive/important the test is. Given that the tests | |
1538 | are also ordered within the list, examining the first is | |
1539 | sufficient. */ | |
dbbbbf3b | 1540 | if ((int) add->tests->type < (int) old->tests->type) |
09051660 RH |
1541 | insert_before = old; |
1542 | } | |
de6a431b | 1543 | |
09051660 RH |
1544 | if (insert_before == NULL) |
1545 | { | |
1546 | add->next = NULL; | |
1547 | add->prev = oldh->last; | |
1548 | oldh->last->next = add; | |
1549 | oldh->last = add; | |
1550 | } | |
1551 | else | |
1552 | { | |
1553 | if ((add->prev = insert_before->prev) != NULL) | |
1554 | add->prev->next = add; | |
1555 | else | |
1556 | oldh->first = add; | |
1557 | add->next = insert_before; | |
1558 | insert_before->prev = add; | |
1559 | } | |
1560 | ||
1561 | merged_nodes:; | |
1562 | } | |
1563 | } | |
1564 | \f | |
5b7c7046 | 1565 | /* Walk the tree looking for sub-nodes that perform common tests. |
09051660 RH |
1566 | Factor out the common test into a new node. This enables us |
1567 | (depending on the test type) to emit switch statements later. */ | |
1568 | ||
1569 | static void | |
3d7aafde | 1570 | factor_tests (struct decision_head *head) |
09051660 RH |
1571 | { |
1572 | struct decision *first, *next; | |
e0689256 | 1573 | |
09051660 RH |
1574 | for (first = head->first; first && first->next; first = next) |
1575 | { | |
1576 | enum decision_type type; | |
8ad97cfc | 1577 | struct decision *new_dec, *old_last; |
e0689256 | 1578 | |
09051660 RH |
1579 | type = first->tests->type; |
1580 | next = first->next; | |
e0689256 | 1581 | |
09051660 RH |
1582 | /* Want at least two compatible sequential nodes. */ |
1583 | if (next->tests->type != type) | |
1584 | continue; | |
ec65fa66 | 1585 | |
5b7c7046 | 1586 | /* Don't want all node types, just those we can turn into |
09051660 RH |
1587 | switch statements. */ |
1588 | if (type != DT_mode | |
1589 | && type != DT_code | |
1590 | && type != DT_veclen | |
1591 | && type != DT_elt_zero_int | |
1592 | && type != DT_elt_one_int | |
070ef6f4 | 1593 | && type != DT_elt_zero_wide_safe) |
e0689256 | 1594 | continue; |
ec65fa66 | 1595 | |
09051660 RH |
1596 | /* If we'd been performing more than one test, create a new node |
1597 | below our first test. */ | |
1598 | if (first->tests->next != NULL) | |
1599 | { | |
8ad97cfc KG |
1600 | new_dec = new_decision (first->position, &first->success); |
1601 | new_dec->tests = first->tests->next; | |
09051660 RH |
1602 | first->tests->next = NULL; |
1603 | } | |
5b7c7046 | 1604 | |
09051660 RH |
1605 | /* Crop the node tree off after our first test. */ |
1606 | first->next = NULL; | |
1607 | old_last = head->last; | |
1608 | head->last = first; | |
1609 | ||
1610 | /* For each compatible test, adjust to perform only one test in | |
1611 | the top level node, then merge the node back into the tree. */ | |
1612 | do | |
1613 | { | |
1614 | struct decision_head h; | |
1615 | ||
1616 | if (next->tests->next != NULL) | |
1617 | { | |
8ad97cfc KG |
1618 | new_dec = new_decision (next->position, &next->success); |
1619 | new_dec->tests = next->tests->next; | |
09051660 RH |
1620 | next->tests->next = NULL; |
1621 | } | |
8ad97cfc | 1622 | new_dec = next; |
09051660 | 1623 | next = next->next; |
8ad97cfc KG |
1624 | new_dec->next = NULL; |
1625 | h.first = h.last = new_dec; | |
ec65fa66 | 1626 | |
09051660 RH |
1627 | merge_trees (head, &h); |
1628 | } | |
1629 | while (next && next->tests->type == type); | |
ec65fa66 | 1630 | |
09051660 RH |
1631 | /* After we run out of compatible tests, graft the remaining nodes |
1632 | back onto the tree. */ | |
1633 | if (next) | |
e0689256 | 1634 | { |
09051660 RH |
1635 | next->prev = head->last; |
1636 | head->last->next = next; | |
1637 | head->last = old_last; | |
e0689256 | 1638 | } |
09051660 | 1639 | } |
ec65fa66 | 1640 | |
09051660 RH |
1641 | /* Recurse. */ |
1642 | for (first = head->first; first; first = first->next) | |
1643 | factor_tests (&first->success); | |
1644 | } | |
1645 | ||
1646 | /* After factoring, try to simplify the tests on any one node. | |
1647 | Tests that are useful for switch statements are recognizable | |
1648 | by having only a single test on a node -- we'll be manipulating | |
1649 | nodes with multiple tests: | |
1650 | ||
1651 | If we have mode tests or code tests that are redundant with | |
1652 | predicates, remove them. */ | |
1653 | ||
1654 | static void | |
3d7aafde | 1655 | simplify_tests (struct decision_head *head) |
09051660 RH |
1656 | { |
1657 | struct decision *tree; | |
1658 | ||
1659 | for (tree = head->first; tree; tree = tree->next) | |
1660 | { | |
1661 | struct decision_test *a, *b; | |
1662 | ||
1663 | a = tree->tests; | |
1664 | b = a->next; | |
1665 | if (b == NULL) | |
1666 | continue; | |
1667 | ||
1668 | /* Find a predicate node. */ | |
1669 | while (b && b->type != DT_pred) | |
1670 | b = b->next; | |
1671 | if (b) | |
e0689256 | 1672 | { |
09051660 RH |
1673 | /* Due to how these tests are constructed, we don't even need |
1674 | to check that the mode and code are compatible -- they were | |
1675 | generated from the predicate in the first place. */ | |
1676 | while (a->type == DT_mode || a->type == DT_code) | |
1677 | a = a->next; | |
1678 | tree->tests = a; | |
e0689256 RK |
1679 | } |
1680 | } | |
ec65fa66 | 1681 | |
09051660 RH |
1682 | /* Recurse. */ |
1683 | for (tree = head->first; tree; tree = tree->next) | |
1684 | simplify_tests (&tree->success); | |
ec65fa66 | 1685 | } |
09051660 | 1686 | |
e0689256 RK |
1687 | /* Count the number of subnodes of HEAD. If the number is high enough, |
1688 | make the first node in HEAD start a separate subroutine in the C code | |
09051660 | 1689 | that is generated. */ |
ec65fa66 RK |
1690 | |
1691 | static int | |
3d7aafde | 1692 | break_out_subroutines (struct decision_head *head, int initial) |
ec65fa66 RK |
1693 | { |
1694 | int size = 0; | |
87bd0490 | 1695 | struct decision *sub; |
e0689256 | 1696 | |
09051660 RH |
1697 | for (sub = head->first; sub; sub = sub->next) |
1698 | size += 1 + break_out_subroutines (&sub->success, 0); | |
e0689256 RK |
1699 | |
1700 | if (size > SUBROUTINE_THRESHOLD && ! initial) | |
ec65fa66 | 1701 | { |
09051660 | 1702 | head->first->subroutine_number = ++next_subroutine_number; |
ec65fa66 RK |
1703 | size = 1; |
1704 | } | |
1705 | return size; | |
1706 | } | |
09051660 RH |
1707 | |
1708 | /* For each node p, find the next alternative that might be true | |
1709 | when p is true. */ | |
ec65fa66 RK |
1710 | |
1711 | static void | |
3d7aafde | 1712 | find_afterward (struct decision_head *head, struct decision *real_afterward) |
ec65fa66 | 1713 | { |
09051660 | 1714 | struct decision *p, *q, *afterward; |
69277eec | 1715 | |
a1f300c0 | 1716 | /* We can't propagate alternatives across subroutine boundaries. |
09051660 | 1717 | This is not incorrect, merely a minor optimization loss. */ |
ec65fa66 | 1718 | |
09051660 RH |
1719 | p = head->first; |
1720 | afterward = (p->subroutine_number > 0 ? NULL : real_afterward); | |
e0689256 | 1721 | |
09051660 | 1722 | for ( ; p ; p = p->next) |
e0689256 | 1723 | { |
09051660 RH |
1724 | /* Find the next node that might be true if this one fails. */ |
1725 | for (q = p->next; q ; q = q->next) | |
1726 | if (maybe_both_true (p, q, 1)) | |
1727 | break; | |
e0689256 | 1728 | |
5b7c7046 | 1729 | /* If we reached the end of the list without finding one, |
09051660 RH |
1730 | use the incoming afterward position. */ |
1731 | if (!q) | |
1732 | q = afterward; | |
1733 | p->afterward = q; | |
1734 | if (q) | |
1735 | q->need_label = 1; | |
e0689256 RK |
1736 | } |
1737 | ||
09051660 RH |
1738 | /* Recurse. */ |
1739 | for (p = head->first; p ; p = p->next) | |
1740 | if (p->success.first) | |
1741 | find_afterward (&p->success, p->afterward); | |
1742 | ||
1743 | /* When we are generating a subroutine, record the real afterward | |
1744 | position in the first node where write_tree can find it, and we | |
1745 | can do the right thing at the subroutine call site. */ | |
1746 | p = head->first; | |
1747 | if (p->subroutine_number > 0) | |
1748 | p->afterward = real_afterward; | |
1749 | } | |
1750 | \f | |
1751 | /* Assuming that the state of argument is denoted by OLDPOS, take whatever | |
1752 | actions are necessary to move to NEWPOS. If we fail to move to the | |
cc2902df | 1753 | new state, branch to node AFTERWARD if nonzero, otherwise return. |
e0689256 | 1754 | |
09051660 | 1755 | Failure to move to the new state can only occur if we are trying to |
dc297297 | 1756 | match multiple insns and we try to step past the end of the stream. */ |
e0689256 | 1757 | |
09051660 | 1758 | static void |
0cd6c85a | 1759 | change_state (const char *oldpos, const char *newpos, const char *indent) |
09051660 RH |
1760 | { |
1761 | int odepth = strlen (oldpos); | |
1762 | int ndepth = strlen (newpos); | |
1763 | int depth; | |
1764 | int old_has_insn, new_has_insn; | |
e0689256 | 1765 | |
09051660 RH |
1766 | /* Pop up as many levels as necessary. */ |
1767 | for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth) | |
1768 | continue; | |
ec65fa66 | 1769 | |
09051660 RH |
1770 | /* Hunt for the last [A-Z] in both strings. */ |
1771 | for (old_has_insn = odepth - 1; old_has_insn >= 0; --old_has_insn) | |
0df6c2c7 | 1772 | if (ISUPPER (oldpos[old_has_insn])) |
09051660 | 1773 | break; |
0deeec4e | 1774 | for (new_has_insn = ndepth - 1; new_has_insn >= 0; --new_has_insn) |
0df6c2c7 | 1775 | if (ISUPPER (newpos[new_has_insn])) |
09051660 | 1776 | break; |
e0689256 | 1777 | |
09051660 RH |
1778 | /* Go down to desired level. */ |
1779 | while (depth < ndepth) | |
1780 | { | |
dc297297 | 1781 | /* It's a different insn from the first one. */ |
0df6c2c7 | 1782 | if (ISUPPER (newpos[depth])) |
ec65fa66 | 1783 | { |
0cd6c85a PB |
1784 | printf ("%stem = peep2_next_insn (%d);\n", |
1785 | indent, newpos[depth] - 'A'); | |
23280139 | 1786 | printf ("%sx%d = PATTERN (tem);\n", indent, depth + 1); |
ec65fa66 | 1787 | } |
0df6c2c7 | 1788 | else if (ISLOWER (newpos[depth])) |
09051660 RH |
1789 | printf ("%sx%d = XVECEXP (x%d, 0, %d);\n", |
1790 | indent, depth + 1, depth, newpos[depth] - 'a'); | |
1791 | else | |
1792 | printf ("%sx%d = XEXP (x%d, %c);\n", | |
1793 | indent, depth + 1, depth, newpos[depth]); | |
1794 | ++depth; | |
1795 | } | |
1796 | } | |
1797 | \f | |
1798 | /* Print the enumerator constant for CODE -- the upcase version of | |
1799 | the name. */ | |
1800 | ||
1801 | static void | |
3d7aafde | 1802 | print_code (enum rtx_code code) |
09051660 | 1803 | { |
b3694847 | 1804 | const char *p; |
09051660 RH |
1805 | for (p = GET_RTX_NAME (code); *p; p++) |
1806 | putchar (TOUPPER (*p)); | |
1807 | } | |
ec65fa66 | 1808 | |
09051660 | 1809 | /* Emit code to cross an afterward link -- change state and branch. */ |
ec65fa66 | 1810 | |
09051660 | 1811 | static void |
3d7aafde AJ |
1812 | write_afterward (struct decision *start, struct decision *afterward, |
1813 | const char *indent) | |
09051660 RH |
1814 | { |
1815 | if (!afterward || start->subroutine_number > 0) | |
1816 | printf("%sgoto ret0;\n", indent); | |
1817 | else | |
1818 | { | |
0cd6c85a | 1819 | change_state (start->position, afterward->position, indent); |
09051660 RH |
1820 | printf ("%sgoto L%d;\n", indent, afterward->number); |
1821 | } | |
1822 | } | |
e0689256 | 1823 | |
4f2ca7f5 RH |
1824 | /* Emit a HOST_WIDE_INT as an integer constant expression. We need to take |
1825 | special care to avoid "decimal constant is so large that it is unsigned" | |
1826 | warnings in the resulting code. */ | |
1827 | ||
1828 | static void | |
1829 | print_host_wide_int (HOST_WIDE_INT val) | |
1830 | { | |
1831 | HOST_WIDE_INT min = (unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1); | |
1832 | if (val == min) | |
1833 | printf ("(" HOST_WIDE_INT_PRINT_DEC_C "-1)", val + 1); | |
1834 | else | |
1835 | printf (HOST_WIDE_INT_PRINT_DEC_C, val); | |
1836 | } | |
1837 | ||
5b7c7046 | 1838 | /* Emit a switch statement, if possible, for an initial sequence of |
09051660 | 1839 | nodes at START. Return the first node yet untested. */ |
e0689256 | 1840 | |
09051660 | 1841 | static struct decision * |
3d7aafde | 1842 | write_switch (struct decision *start, int depth) |
09051660 RH |
1843 | { |
1844 | struct decision *p = start; | |
1845 | enum decision_type type = p->tests->type; | |
1651ab85 | 1846 | struct decision *needs_label = NULL; |
ec65fa66 | 1847 | |
09051660 RH |
1848 | /* If we have two or more nodes in sequence that test the same one |
1849 | thing, we may be able to use a switch statement. */ | |
e0689256 | 1850 | |
09051660 RH |
1851 | if (!p->next |
1852 | || p->tests->next | |
1853 | || p->next->tests->type != type | |
2cec75a1 RH |
1854 | || p->next->tests->next |
1855 | || nodes_identical_1 (p->tests, p->next->tests)) | |
09051660 | 1856 | return p; |
e0689256 | 1857 | |
09051660 RH |
1858 | /* DT_code is special in that we can do interesting things with |
1859 | known predicates at the same time. */ | |
1860 | if (type == DT_code) | |
1861 | { | |
1862 | char codemap[NUM_RTX_CODE]; | |
1863 | struct decision *ret; | |
1e193337 | 1864 | RTX_CODE code; |
ec65fa66 | 1865 | |
09051660 | 1866 | memset (codemap, 0, sizeof(codemap)); |
ec65fa66 | 1867 | |
09051660 | 1868 | printf (" switch (GET_CODE (x%d))\n {\n", depth); |
1e193337 | 1869 | code = p->tests->u.code; |
5b7c7046 | 1870 | do |
ec65fa66 | 1871 | { |
1651ab85 AO |
1872 | if (p != start && p->need_label && needs_label == NULL) |
1873 | needs_label = p; | |
1874 | ||
09051660 RH |
1875 | printf (" case "); |
1876 | print_code (code); | |
1877 | printf (":\n goto L%d;\n", p->success.first->number); | |
1878 | p->success.first->need_label = 1; | |
1879 | ||
1880 | codemap[code] = 1; | |
1881 | p = p->next; | |
1882 | } | |
1e193337 RH |
1883 | while (p |
1884 | && ! p->tests->next | |
1885 | && p->tests->type == DT_code | |
1886 | && ! codemap[code = p->tests->u.code]); | |
09051660 RH |
1887 | |
1888 | /* If P is testing a predicate that we know about and we haven't | |
1889 | seen any of the codes that are valid for the predicate, we can | |
1890 | write a series of "case" statement, one for each possible code. | |
1891 | Since we are already in a switch, these redundant tests are very | |
1892 | cheap and will reduce the number of predicates called. */ | |
1893 | ||
1894 | /* Note that while we write out cases for these predicates here, | |
1895 | we don't actually write the test here, as it gets kinda messy. | |
1896 | It is trivial to leave this to later by telling our caller that | |
1897 | we only processed the CODE tests. */ | |
1651ab85 AO |
1898 | if (needs_label != NULL) |
1899 | ret = needs_label; | |
1900 | else | |
1901 | ret = p; | |
09051660 | 1902 | |
e543e219 | 1903 | while (p && p->tests->type == DT_pred && p->tests->u.pred.data) |
09051660 | 1904 | { |
e543e219 | 1905 | const struct pred_data *data = p->tests->u.pred.data; |
32e8bb8e ILT |
1906 | int c; |
1907 | ||
e543e219 ZW |
1908 | for (c = 0; c < NUM_RTX_CODE; c++) |
1909 | if (codemap[c] && data->codes[c]) | |
09051660 | 1910 | goto pred_done; |
e0689256 | 1911 | |
e543e219 ZW |
1912 | for (c = 0; c < NUM_RTX_CODE; c++) |
1913 | if (data->codes[c]) | |
1914 | { | |
1915 | fputs (" case ", stdout); | |
32e8bb8e | 1916 | print_code ((enum rtx_code) c); |
e543e219 ZW |
1917 | fputs (":\n", stdout); |
1918 | codemap[c] = 1; | |
1919 | } | |
e0689256 | 1920 | |
09051660 RH |
1921 | printf (" goto L%d;\n", p->number); |
1922 | p->need_label = 1; | |
1923 | p = p->next; | |
ec65fa66 RK |
1924 | } |
1925 | ||
09051660 RH |
1926 | pred_done: |
1927 | /* Make the default case skip the predicates we managed to match. */ | |
e0689256 | 1928 | |
09051660 RH |
1929 | printf (" default:\n"); |
1930 | if (p != ret) | |
ec65fa66 | 1931 | { |
09051660 | 1932 | if (p) |
b030d598 | 1933 | { |
09051660 RH |
1934 | printf (" goto L%d;\n", p->number); |
1935 | p->need_label = 1; | |
b030d598 | 1936 | } |
e0689256 | 1937 | else |
09051660 | 1938 | write_afterward (start, start->afterward, " "); |
ec65fa66 | 1939 | } |
ec65fa66 | 1940 | else |
09051660 RH |
1941 | printf (" break;\n"); |
1942 | printf (" }\n"); | |
1943 | ||
1944 | return ret; | |
1945 | } | |
1946 | else if (type == DT_mode | |
1947 | || type == DT_veclen | |
1948 | || type == DT_elt_zero_int | |
1949 | || type == DT_elt_one_int | |
070ef6f4 | 1950 | || type == DT_elt_zero_wide_safe) |
09051660 | 1951 | { |
9591d210 | 1952 | const char *indent = ""; |
9e9f3ede | 1953 | |
9591d210 JH |
1954 | /* We cast switch parameter to integer, so we must ensure that the value |
1955 | fits. */ | |
1956 | if (type == DT_elt_zero_wide_safe) | |
1957 | { | |
1958 | indent = " "; | |
1959 | printf(" if ((int) XWINT (x%d, 0) == XWINT (x%d, 0))\n", depth, depth); | |
1960 | } | |
1961 | printf ("%s switch (", indent); | |
09051660 RH |
1962 | switch (type) |
1963 | { | |
1964 | case DT_mode: | |
c8d8ed65 | 1965 | printf ("GET_MODE (x%d)", depth); |
09051660 RH |
1966 | break; |
1967 | case DT_veclen: | |
c8d8ed65 | 1968 | printf ("XVECLEN (x%d, 0)", depth); |
09051660 RH |
1969 | break; |
1970 | case DT_elt_zero_int: | |
c8d8ed65 | 1971 | printf ("XINT (x%d, 0)", depth); |
09051660 RH |
1972 | break; |
1973 | case DT_elt_one_int: | |
c8d8ed65 | 1974 | printf ("XINT (x%d, 1)", depth); |
09051660 | 1975 | break; |
070ef6f4 | 1976 | case DT_elt_zero_wide_safe: |
c8d8ed65 RK |
1977 | /* Convert result of XWINT to int for portability since some C |
1978 | compilers won't do it and some will. */ | |
1979 | printf ("(int) XWINT (x%d, 0)", depth); | |
09051660 RH |
1980 | break; |
1981 | default: | |
b2d59f6f | 1982 | gcc_unreachable (); |
09051660 | 1983 | } |
9591d210 | 1984 | printf (")\n%s {\n", indent); |
cba998bf | 1985 | |
09051660 | 1986 | do |
e0689256 | 1987 | { |
2cec75a1 RH |
1988 | /* Merge trees will not unify identical nodes if their |
1989 | sub-nodes are at different levels. Thus we must check | |
1990 | for duplicate cases. */ | |
1991 | struct decision *q; | |
1992 | for (q = start; q != p; q = q->next) | |
1993 | if (nodes_identical_1 (p->tests, q->tests)) | |
1994 | goto case_done; | |
1995 | ||
1651ab85 AO |
1996 | if (p != start && p->need_label && needs_label == NULL) |
1997 | needs_label = p; | |
1998 | ||
9591d210 | 1999 | printf ("%s case ", indent); |
09051660 | 2000 | switch (type) |
cba998bf | 2001 | { |
09051660 RH |
2002 | case DT_mode: |
2003 | printf ("%smode", GET_MODE_NAME (p->tests->u.mode)); | |
2004 | break; | |
2005 | case DT_veclen: | |
2006 | printf ("%d", p->tests->u.veclen); | |
2007 | break; | |
2008 | case DT_elt_zero_int: | |
2009 | case DT_elt_one_int: | |
2010 | case DT_elt_zero_wide: | |
070ef6f4 | 2011 | case DT_elt_zero_wide_safe: |
4f2ca7f5 | 2012 | print_host_wide_int (p->tests->u.intval); |
09051660 RH |
2013 | break; |
2014 | default: | |
b2d59f6f | 2015 | gcc_unreachable (); |
cba998bf | 2016 | } |
9591d210 | 2017 | printf (":\n%s goto L%d;\n", indent, p->success.first->number); |
09051660 | 2018 | p->success.first->need_label = 1; |
cba998bf | 2019 | |
09051660 | 2020 | p = p->next; |
e0689256 | 2021 | } |
09051660 | 2022 | while (p && p->tests->type == type && !p->tests->next); |
2cec75a1 RH |
2023 | |
2024 | case_done: | |
9591d210 JH |
2025 | printf ("%s default:\n%s break;\n%s }\n", |
2026 | indent, indent, indent); | |
ec65fa66 | 2027 | |
1651ab85 | 2028 | return needs_label != NULL ? needs_label : p; |
09051660 RH |
2029 | } |
2030 | else | |
2031 | { | |
fbe5a4a6 | 2032 | /* None of the other tests are amenable. */ |
09051660 RH |
2033 | return p; |
2034 | } | |
2035 | } | |
ec65fa66 | 2036 | |
09051660 | 2037 | /* Emit code for one test. */ |
e0689256 | 2038 | |
09051660 | 2039 | static void |
3d7aafde AJ |
2040 | write_cond (struct decision_test *p, int depth, |
2041 | enum routine_type subroutine_type) | |
09051660 RH |
2042 | { |
2043 | switch (p->type) | |
2044 | { | |
0cd6c85a PB |
2045 | case DT_num_insns: |
2046 | printf ("peep2_current_count >= %d", p->u.num_insns); | |
2047 | break; | |
2048 | ||
09051660 RH |
2049 | case DT_mode: |
2050 | printf ("GET_MODE (x%d) == %smode", depth, GET_MODE_NAME (p->u.mode)); | |
2051 | break; | |
e0689256 | 2052 | |
09051660 RH |
2053 | case DT_code: |
2054 | printf ("GET_CODE (x%d) == ", depth); | |
2055 | print_code (p->u.code); | |
2056 | break; | |
2057 | ||
2058 | case DT_veclen: | |
2059 | printf ("XVECLEN (x%d, 0) == %d", depth, p->u.veclen); | |
2060 | break; | |
2061 | ||
2062 | case DT_elt_zero_int: | |
2063 | printf ("XINT (x%d, 0) == %d", depth, (int) p->u.intval); | |
2064 | break; | |
2065 | ||
2066 | case DT_elt_one_int: | |
2067 | printf ("XINT (x%d, 1) == %d", depth, (int) p->u.intval); | |
2068 | break; | |
2069 | ||
2070 | case DT_elt_zero_wide: | |
070ef6f4 | 2071 | case DT_elt_zero_wide_safe: |
09051660 | 2072 | printf ("XWINT (x%d, 0) == ", depth); |
4f2ca7f5 | 2073 | print_host_wide_int (p->u.intval); |
09051660 RH |
2074 | break; |
2075 | ||
ccdc1703 KH |
2076 | case DT_const_int: |
2077 | printf ("x%d == const_int_rtx[MAX_SAVED_CONST_INT + (%d)]", | |
2078 | depth, (int) p->u.intval); | |
2079 | break; | |
2080 | ||
521b9224 RH |
2081 | case DT_veclen_ge: |
2082 | printf ("XVECLEN (x%d, 0) >= %d", depth, p->u.veclen); | |
2083 | break; | |
2084 | ||
09051660 RH |
2085 | case DT_dup: |
2086 | printf ("rtx_equal_p (x%d, operands[%d])", depth, p->u.dup); | |
2087 | break; | |
2088 | ||
2089 | case DT_pred: | |
2090 | printf ("%s (x%d, %smode)", p->u.pred.name, depth, | |
2091 | GET_MODE_NAME (p->u.pred.mode)); | |
2092 | break; | |
2093 | ||
2094 | case DT_c_test: | |
7445392c | 2095 | print_c_condition (p->u.c_test); |
09051660 RH |
2096 | break; |
2097 | ||
2098 | case DT_accept_insn: | |
b2d59f6f NS |
2099 | gcc_assert (subroutine_type == RECOG); |
2100 | gcc_assert (p->u.insn.num_clobbers_to_add); | |
2101 | printf ("pnum_clobbers != NULL"); | |
09051660 | 2102 | break; |
ec65fa66 | 2103 | |
09051660 | 2104 | default: |
b2d59f6f | 2105 | gcc_unreachable (); |
e0689256 | 2106 | } |
09051660 | 2107 | } |
ec65fa66 | 2108 | |
09051660 RH |
2109 | /* Emit code for one action. The previous tests have succeeded; |
2110 | TEST is the last of the chain. In the normal case we simply | |
2111 | perform a state change. For the `accept' tests we must do more work. */ | |
ec65fa66 | 2112 | |
09051660 | 2113 | static void |
3d7aafde AJ |
2114 | write_action (struct decision *p, struct decision_test *test, |
2115 | int depth, int uncond, struct decision *success, | |
2116 | enum routine_type subroutine_type) | |
09051660 RH |
2117 | { |
2118 | const char *indent; | |
2119 | int want_close = 0; | |
2120 | ||
2121 | if (uncond) | |
2122 | indent = " "; | |
2123 | else if (test->type == DT_accept_op || test->type == DT_accept_insn) | |
e0689256 | 2124 | { |
09051660 RH |
2125 | fputs (" {\n", stdout); |
2126 | indent = " "; | |
2127 | want_close = 1; | |
e0689256 | 2128 | } |
09051660 RH |
2129 | else |
2130 | indent = " "; | |
ec65fa66 | 2131 | |
09051660 | 2132 | if (test->type == DT_accept_op) |
e0689256 | 2133 | { |
09051660 RH |
2134 | printf("%soperands[%d] = x%d;\n", indent, test->u.opno, depth); |
2135 | ||
2136 | /* Only allow DT_accept_insn to follow. */ | |
2137 | if (test->next) | |
2138 | { | |
2139 | test = test->next; | |
b2d59f6f | 2140 | gcc_assert (test->type == DT_accept_insn); |
09051660 | 2141 | } |
ec65fa66 RK |
2142 | } |
2143 | ||
09051660 | 2144 | /* Sanity check that we're now at the end of the list of tests. */ |
b2d59f6f | 2145 | gcc_assert (!test->next); |
ec65fa66 | 2146 | |
09051660 | 2147 | if (test->type == DT_accept_insn) |
ec65fa66 | 2148 | { |
09051660 RH |
2149 | switch (subroutine_type) |
2150 | { | |
2151 | case RECOG: | |
2152 | if (test->u.insn.num_clobbers_to_add != 0) | |
2153 | printf ("%s*pnum_clobbers = %d;\n", | |
2154 | indent, test->u.insn.num_clobbers_to_add); | |
1e9c8405 RS |
2155 | printf ("%sreturn %d; /* %s */\n", indent, |
2156 | test->u.insn.code_number, | |
0458fe77 | 2157 | get_insn_name (test->u.insn.code_number)); |
09051660 RH |
2158 | break; |
2159 | ||
2160 | case SPLIT: | |
a406f566 | 2161 | printf ("%sreturn gen_split_%d (insn, operands);\n", |
09051660 RH |
2162 | indent, test->u.insn.code_number); |
2163 | break; | |
2164 | ||
2165 | case PEEPHOLE2: | |
23280139 RH |
2166 | { |
2167 | int match_len = 0, i; | |
2168 | ||
2169 | for (i = strlen (p->position) - 1; i >= 0; --i) | |
0df6c2c7 | 2170 | if (ISUPPER (p->position[i])) |
23280139 RH |
2171 | { |
2172 | match_len = p->position[i] - 'A'; | |
2173 | break; | |
2174 | } | |
2175 | printf ("%s*_pmatch_len = %d;\n", indent, match_len); | |
2176 | printf ("%stem = gen_peephole2_%d (insn, operands);\n", | |
2177 | indent, test->u.insn.code_number); | |
2178 | printf ("%sif (tem != 0)\n%s return tem;\n", indent, indent); | |
2179 | } | |
09051660 RH |
2180 | break; |
2181 | ||
2182 | default: | |
b2d59f6f | 2183 | gcc_unreachable (); |
09051660 | 2184 | } |
ec65fa66 RK |
2185 | } |
2186 | else | |
09051660 RH |
2187 | { |
2188 | printf("%sgoto L%d;\n", indent, success->number); | |
2189 | success->need_label = 1; | |
2190 | } | |
ec65fa66 | 2191 | |
09051660 RH |
2192 | if (want_close) |
2193 | fputs (" }\n", stdout); | |
ec65fa66 RK |
2194 | } |
2195 | ||
09051660 RH |
2196 | /* Return 1 if the test is always true and has no fallthru path. Return -1 |
2197 | if the test does have a fallthru path, but requires that the condition be | |
2198 | terminated. Otherwise return 0 for a normal test. */ | |
2199 | /* ??? is_unconditional is a stupid name for a tri-state function. */ | |
2200 | ||
ec65fa66 | 2201 | static int |
3d7aafde | 2202 | is_unconditional (struct decision_test *t, enum routine_type subroutine_type) |
ec65fa66 | 2203 | { |
09051660 RH |
2204 | if (t->type == DT_accept_op) |
2205 | return 1; | |
ec65fa66 | 2206 | |
09051660 RH |
2207 | if (t->type == DT_accept_insn) |
2208 | { | |
2209 | switch (subroutine_type) | |
2210 | { | |
2211 | case RECOG: | |
2212 | return (t->u.insn.num_clobbers_to_add == 0); | |
2213 | case SPLIT: | |
2214 | return 1; | |
2215 | case PEEPHOLE2: | |
2216 | return -1; | |
2217 | default: | |
b2d59f6f | 2218 | gcc_unreachable (); |
09051660 RH |
2219 | } |
2220 | } | |
ec65fa66 | 2221 | |
09051660 | 2222 | return 0; |
ec65fa66 RK |
2223 | } |
2224 | ||
09051660 RH |
2225 | /* Emit code for one node -- the conditional and the accompanying action. |
2226 | Return true if there is no fallthru path. */ | |
2227 | ||
ec65fa66 | 2228 | static int |
3d7aafde AJ |
2229 | write_node (struct decision *p, int depth, |
2230 | enum routine_type subroutine_type) | |
ec65fa66 | 2231 | { |
09051660 RH |
2232 | struct decision_test *test, *last_test; |
2233 | int uncond; | |
ec65fa66 | 2234 | |
ccdc1703 KH |
2235 | /* Scan the tests and simplify comparisons against small |
2236 | constants. */ | |
2237 | for (test = p->tests; test; test = test->next) | |
2238 | { | |
2239 | if (test->type == DT_code | |
2240 | && test->u.code == CONST_INT | |
2241 | && test->next | |
2242 | && test->next->type == DT_elt_zero_wide_safe | |
2243 | && -MAX_SAVED_CONST_INT <= test->next->u.intval | |
2244 | && test->next->u.intval <= MAX_SAVED_CONST_INT) | |
2245 | { | |
2246 | test->type = DT_const_int; | |
2247 | test->u.intval = test->next->u.intval; | |
2248 | test->next = test->next->next; | |
2249 | } | |
2250 | } | |
2251 | ||
09051660 RH |
2252 | last_test = test = p->tests; |
2253 | uncond = is_unconditional (test, subroutine_type); | |
2254 | if (uncond == 0) | |
2255 | { | |
2256 | printf (" if ("); | |
2257 | write_cond (test, depth, subroutine_type); | |
2258 | ||
2259 | while ((test = test->next) != NULL) | |
2260 | { | |
09051660 | 2261 | last_test = test; |
be2c39f8 | 2262 | if (is_unconditional (test, subroutine_type)) |
09051660 RH |
2263 | break; |
2264 | ||
2265 | printf ("\n && "); | |
2266 | write_cond (test, depth, subroutine_type); | |
2267 | } | |
2268 | ||
2269 | printf (")\n"); | |
2270 | } | |
2271 | ||
23280139 | 2272 | write_action (p, last_test, depth, uncond, p->success.first, subroutine_type); |
09051660 RH |
2273 | |
2274 | return uncond > 0; | |
ec65fa66 RK |
2275 | } |
2276 | ||
09051660 RH |
2277 | /* Emit code for all of the sibling nodes of HEAD. */ |
2278 | ||
ec65fa66 | 2279 | static void |
3d7aafde AJ |
2280 | write_tree_1 (struct decision_head *head, int depth, |
2281 | enum routine_type subroutine_type) | |
ec65fa66 | 2282 | { |
09051660 RH |
2283 | struct decision *p, *next; |
2284 | int uncond = 0; | |
e0689256 | 2285 | |
09051660 RH |
2286 | for (p = head->first; p ; p = next) |
2287 | { | |
2288 | /* The label for the first element was printed in write_tree. */ | |
2289 | if (p != head->first && p->need_label) | |
2290 | OUTPUT_LABEL (" ", p->number); | |
2291 | ||
2292 | /* Attempt to write a switch statement for a whole sequence. */ | |
2293 | next = write_switch (p, depth); | |
2294 | if (p != next) | |
2295 | uncond = 0; | |
2296 | else | |
2297 | { | |
2298 | /* Failed -- fall back and write one node. */ | |
2299 | uncond = write_node (p, depth, subroutine_type); | |
2300 | next = p->next; | |
2301 | } | |
2302 | } | |
e0689256 | 2303 | |
09051660 RH |
2304 | /* Finished with this chain. Close a fallthru path by branching |
2305 | to the afterward node. */ | |
2306 | if (! uncond) | |
2307 | write_afterward (head->last, head->last->afterward, " "); | |
2308 | } | |
e0689256 | 2309 | |
09051660 RH |
2310 | /* Write out the decision tree starting at HEAD. PREVPOS is the |
2311 | position at the node that branched to this node. */ | |
e0689256 RK |
2312 | |
2313 | static void | |
3d7aafde AJ |
2314 | write_tree (struct decision_head *head, const char *prevpos, |
2315 | enum routine_type type, int initial) | |
e0689256 | 2316 | { |
b3694847 | 2317 | struct decision *p = head->first; |
e0689256 | 2318 | |
09051660 RH |
2319 | putchar ('\n'); |
2320 | if (p->need_label) | |
2321 | OUTPUT_LABEL (" ", p->number); | |
2322 | ||
2323 | if (! initial && p->subroutine_number > 0) | |
e0689256 | 2324 | { |
09051660 RH |
2325 | static const char * const name_prefix[] = { |
2326 | "recog", "split", "peephole2" | |
2327 | }; | |
2328 | ||
2329 | static const char * const call_suffix[] = { | |
23280139 | 2330 | ", pnum_clobbers", "", ", _pmatch_len" |
09051660 | 2331 | }; |
e0689256 | 2332 | |
09051660 RH |
2333 | /* This node has been broken out into a separate subroutine. |
2334 | Call it, test the result, and branch accordingly. */ | |
2335 | ||
2336 | if (p->afterward) | |
e0689256 RK |
2337 | { |
2338 | printf (" tem = %s_%d (x0, insn%s);\n", | |
09051660 | 2339 | name_prefix[type], p->subroutine_number, call_suffix[type]); |
ede7cd44 | 2340 | if (IS_SPLIT (type)) |
09051660 | 2341 | printf (" if (tem != 0)\n return tem;\n"); |
71bde1f3 | 2342 | else |
09051660 RH |
2343 | printf (" if (tem >= 0)\n return tem;\n"); |
2344 | ||
0cd6c85a | 2345 | change_state (p->position, p->afterward->position, " "); |
09051660 | 2346 | printf (" goto L%d;\n", p->afterward->number); |
e0689256 RK |
2347 | } |
2348 | else | |
09051660 RH |
2349 | { |
2350 | printf (" return %s_%d (x0, insn%s);\n", | |
2351 | name_prefix[type], p->subroutine_number, call_suffix[type]); | |
2352 | } | |
e0689256 | 2353 | } |
09051660 RH |
2354 | else |
2355 | { | |
2356 | int depth = strlen (p->position); | |
e0689256 | 2357 | |
0cd6c85a | 2358 | change_state (prevpos, p->position, " "); |
09051660 | 2359 | write_tree_1 (head, depth, type); |
e0689256 | 2360 | |
09051660 RH |
2361 | for (p = head->first; p; p = p->next) |
2362 | if (p->success.first) | |
2363 | write_tree (&p->success, p->position, type, 0); | |
2364 | } | |
e0689256 RK |
2365 | } |
2366 | ||
09051660 RH |
2367 | /* Write out a subroutine of type TYPE to do comparisons starting at |
2368 | node TREE. */ | |
ede7cd44 | 2369 | |
09051660 | 2370 | static void |
3d7aafde | 2371 | write_subroutine (struct decision_head *head, enum routine_type type) |
09051660 | 2372 | { |
e8f9b13a | 2373 | int subfunction = head->first ? head->first->subroutine_number : 0; |
09051660 RH |
2374 | const char *s_or_e; |
2375 | char extension[32]; | |
2376 | int i; | |
5b7c7046 | 2377 | |
09051660 | 2378 | s_or_e = subfunction ? "static " : ""; |
e0689256 | 2379 | |
09051660 RH |
2380 | if (subfunction) |
2381 | sprintf (extension, "_%d", subfunction); | |
2382 | else if (type == RECOG) | |
2383 | extension[0] = '\0'; | |
2384 | else | |
2385 | strcpy (extension, "_insns"); | |
2386 | ||
913d0833 KG |
2387 | switch (type) |
2388 | { | |
2389 | case RECOG: | |
913d0833 | 2390 | printf ("%sint\n\ |
6906ba40 | 2391 | recog%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n", s_or_e, extension); |
913d0833 KG |
2392 | break; |
2393 | case SPLIT: | |
913d0833 | 2394 | printf ("%srtx\n\ |
6906ba40 KG |
2395 | split%s (rtx x0 ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n", |
2396 | s_or_e, extension); | |
913d0833 KG |
2397 | break; |
2398 | case PEEPHOLE2: | |
913d0833 | 2399 | printf ("%srtx\n\ |
6906ba40 KG |
2400 | peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pmatch_len ATTRIBUTE_UNUSED)\n", |
2401 | s_or_e, extension); | |
913d0833 KG |
2402 | break; |
2403 | } | |
09051660 | 2404 | |
b3694847 | 2405 | printf ("{\n rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0];\n"); |
09051660 | 2406 | for (i = 1; i <= max_depth; i++) |
b3694847 | 2407 | printf (" rtx x%d ATTRIBUTE_UNUSED;\n", i); |
09051660 | 2408 | |
09051660 RH |
2409 | printf (" %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int"); |
2410 | ||
d90ffc8d JH |
2411 | if (!subfunction) |
2412 | printf (" recog_data.insn = NULL_RTX;\n"); | |
2413 | ||
e8f9b13a RH |
2414 | if (head->first) |
2415 | write_tree (head, "", type, 1); | |
2416 | else | |
2417 | printf (" goto ret0;\n"); | |
09051660 | 2418 | |
09051660 RH |
2419 | printf (" ret0:\n return %d;\n}\n\n", IS_SPLIT (type) ? 0 : -1); |
2420 | } | |
2421 | ||
2422 | /* In break_out_subroutines, we discovered the boundaries for the | |
2423 | subroutines, but did not write them out. Do so now. */ | |
e0689256 | 2424 | |
ec65fa66 | 2425 | static void |
3d7aafde | 2426 | write_subroutines (struct decision_head *head, enum routine_type type) |
ec65fa66 | 2427 | { |
09051660 | 2428 | struct decision *p; |
ec65fa66 | 2429 | |
09051660 RH |
2430 | for (p = head->first; p ; p = p->next) |
2431 | if (p->success.first) | |
2432 | write_subroutines (&p->success, type); | |
ec65fa66 | 2433 | |
09051660 RH |
2434 | if (head->first->subroutine_number > 0) |
2435 | write_subroutine (head, type); | |
2436 | } | |
ede7cd44 | 2437 | |
09051660 | 2438 | /* Begin the output file. */ |
ede7cd44 | 2439 | |
09051660 | 2440 | static void |
3d7aafde | 2441 | write_header (void) |
09051660 RH |
2442 | { |
2443 | puts ("\ | |
2444 | /* Generated automatically by the program `genrecog' from the target\n\ | |
2445 | machine description file. */\n\ | |
2446 | \n\ | |
2447 | #include \"config.h\"\n\ | |
2448 | #include \"system.h\"\n\ | |
4977bab6 ZW |
2449 | #include \"coretypes.h\"\n\ |
2450 | #include \"tm.h\"\n\ | |
09051660 RH |
2451 | #include \"rtl.h\"\n\ |
2452 | #include \"tm_p.h\"\n\ | |
2453 | #include \"function.h\"\n\ | |
2454 | #include \"insn-config.h\"\n\ | |
2455 | #include \"recog.h\"\n\ | |
09051660 RH |
2456 | #include \"output.h\"\n\ |
2457 | #include \"flags.h\"\n\ | |
b1afd7f4 KG |
2458 | #include \"hard-reg-set.h\"\n\ |
2459 | #include \"resource.h\"\n\ | |
04f378ce | 2460 | #include \"toplev.h\"\n\ |
5b7c7046 | 2461 | #include \"reload.h\"\n\ |
5abc5de9 | 2462 | #include \"regs.h\"\n\ |
279bb624 | 2463 | #include \"tm-constrs.h\"\n\ |
09051660 RH |
2464 | \n"); |
2465 | ||
2466 | puts ("\n\ | |
2467 | /* `recog' contains a decision tree that recognizes whether the rtx\n\ | |
2468 | X0 is a valid instruction.\n\ | |
2469 | \n\ | |
2470 | recog returns -1 if the rtx is not valid. If the rtx is valid, recog\n\ | |
2471 | returns a nonnegative number which is the insn code number for the\n\ | |
2472 | pattern that matched. This is the same as the order in the machine\n\ | |
2473 | description of the entry that matched. This number can be used as an\n\ | |
3f6790bf KG |
2474 | index into `insn_data' and other tables.\n"); |
2475 | puts ("\ | |
09051660 RH |
2476 | The third argument to recog is an optional pointer to an int. If\n\ |
2477 | present, recog will accept a pattern if it matches except for missing\n\ | |
2478 | CLOBBER expressions at the end. In that case, the value pointed to by\n\ | |
2479 | the optional pointer will be set to the number of CLOBBERs that need\n\ | |
3f6790bf KG |
2480 | to be added (it should be initialized to zero by the caller). If it"); |
2481 | puts ("\ | |
09051660 RH |
2482 | is set nonzero, the caller should allocate a PARALLEL of the\n\ |
2483 | appropriate size, copy the initial entries, and call add_clobbers\n\ | |
2484 | (found in insn-emit.c) to fill in the CLOBBERs.\n\ | |
2485 | "); | |
2486 | ||
2487 | puts ("\n\ | |
2488 | The function split_insns returns 0 if the rtl could not\n\ | |
2f937369 | 2489 | be split or the split rtl as an INSN list if it can be.\n\ |
09051660 RH |
2490 | \n\ |
2491 | The function peephole2_insns returns 0 if the rtl could not\n\ | |
2f937369 | 2492 | be matched. If there was a match, the new rtl is returned in an INSN list,\n\ |
09051660 RH |
2493 | and LAST_INSN will point to the last recognized insn in the old sequence.\n\ |
2494 | */\n\n"); | |
2495 | } | |
ec65fa66 | 2496 | |
09051660 RH |
2497 | \f |
2498 | /* Construct and return a sequence of decisions | |
2499 | that will recognize INSN. | |
ec65fa66 | 2500 | |
09051660 RH |
2501 | TYPE says what type of routine we are recognizing (RECOG or SPLIT). */ |
2502 | ||
2503 | static struct decision_head | |
3d7aafde | 2504 | make_insn_sequence (rtx insn, enum routine_type type) |
09051660 RH |
2505 | { |
2506 | rtx x; | |
2507 | const char *c_test = XSTR (insn, type == RECOG ? 2 : 1); | |
2199e5fa | 2508 | int truth = maybe_eval_c_test (c_test); |
09051660 RH |
2509 | struct decision *last; |
2510 | struct decision_test *test, **place; | |
2511 | struct decision_head head; | |
3b304f5b | 2512 | char c_test_pos[2]; |
09051660 | 2513 | |
2199e5fa | 2514 | /* We should never see an insn whose C test is false at compile time. */ |
b2d59f6f | 2515 | gcc_assert (truth); |
2199e5fa | 2516 | |
3b304f5b | 2517 | c_test_pos[0] = '\0'; |
09051660 | 2518 | if (type == PEEPHOLE2) |
ec65fa66 | 2519 | { |
09051660 RH |
2520 | int i, j; |
2521 | ||
2522 | /* peephole2 gets special treatment: | |
2523 | - X always gets an outer parallel even if it's only one entry | |
2524 | - we remove all traces of outer-level match_scratch and match_dup | |
2525 | expressions here. */ | |
2526 | x = rtx_alloc (PARALLEL); | |
2527 | PUT_MODE (x, VOIDmode); | |
2528 | XVEC (x, 0) = rtvec_alloc (XVECLEN (insn, 0)); | |
2529 | for (i = j = 0; i < XVECLEN (insn, 0); i++) | |
ede7cd44 | 2530 | { |
09051660 RH |
2531 | rtx tmp = XVECEXP (insn, 0, i); |
2532 | if (GET_CODE (tmp) != MATCH_SCRATCH && GET_CODE (tmp) != MATCH_DUP) | |
2533 | { | |
2534 | XVECEXP (x, 0, j) = tmp; | |
2535 | j++; | |
2536 | } | |
2537 | } | |
2538 | XVECLEN (x, 0) = j; | |
4e9887c7 | 2539 | |
4e9887c7 RH |
2540 | c_test_pos[0] = 'A' + j - 1; |
2541 | c_test_pos[1] = '\0'; | |
09051660 RH |
2542 | } |
2543 | else if (XVECLEN (insn, type == RECOG) == 1) | |
2544 | x = XVECEXP (insn, type == RECOG, 0); | |
2545 | else | |
2546 | { | |
2547 | x = rtx_alloc (PARALLEL); | |
2548 | XVEC (x, 0) = XVEC (insn, type == RECOG); | |
2549 | PUT_MODE (x, VOIDmode); | |
2550 | } | |
2551 | ||
7297e9fc | 2552 | validate_pattern (x, insn, NULL_RTX, 0); |
bcdaba58 | 2553 | |
09051660 RH |
2554 | memset(&head, 0, sizeof(head)); |
2555 | last = add_to_sequence (x, &head, "", type, 1); | |
2556 | ||
2557 | /* Find the end of the test chain on the last node. */ | |
2558 | for (test = last->tests; test->next; test = test->next) | |
2559 | continue; | |
2560 | place = &test->next; | |
2561 | ||
2199e5fa ZW |
2562 | /* Skip the C test if it's known to be true at compile time. */ |
2563 | if (truth == -1) | |
09051660 RH |
2564 | { |
2565 | /* Need a new node if we have another test to add. */ | |
2566 | if (test->type == DT_accept_op) | |
2567 | { | |
4e9887c7 | 2568 | last = new_decision (c_test_pos, &last->success); |
09051660 RH |
2569 | place = &last->tests; |
2570 | } | |
2571 | test = new_decision_test (DT_c_test, &place); | |
2572 | test->u.c_test = c_test; | |
2573 | } | |
2574 | ||
2575 | test = new_decision_test (DT_accept_insn, &place); | |
2576 | test->u.insn.code_number = next_insn_code; | |
bcdaba58 | 2577 | test->u.insn.lineno = pattern_lineno; |
09051660 RH |
2578 | test->u.insn.num_clobbers_to_add = 0; |
2579 | ||
2580 | switch (type) | |
2581 | { | |
2582 | case RECOG: | |
b20b352b | 2583 | /* If this is a DEFINE_INSN and X is a PARALLEL, see if it ends |
09051660 RH |
2584 | with a group of CLOBBERs of (hard) registers or MATCH_SCRATCHes. |
2585 | If so, set up to recognize the pattern without these CLOBBERs. */ | |
2586 | ||
2587 | if (GET_CODE (x) == PARALLEL) | |
2588 | { | |
2589 | int i; | |
2590 | ||
2591 | /* Find the last non-clobber in the parallel. */ | |
2592 | for (i = XVECLEN (x, 0); i > 0; i--) | |
ede7cd44 | 2593 | { |
09051660 RH |
2594 | rtx y = XVECEXP (x, 0, i - 1); |
2595 | if (GET_CODE (y) != CLOBBER | |
f8cfc6aa | 2596 | || (!REG_P (XEXP (y, 0)) |
09051660 RH |
2597 | && GET_CODE (XEXP (y, 0)) != MATCH_SCRATCH)) |
2598 | break; | |
ede7cd44 | 2599 | } |
09051660 RH |
2600 | |
2601 | if (i != XVECLEN (x, 0)) | |
ede7cd44 | 2602 | { |
8ad97cfc | 2603 | rtx new_rtx; |
09051660 | 2604 | struct decision_head clobber_head; |
ede7cd44 | 2605 | |
09051660 RH |
2606 | /* Build a similar insn without the clobbers. */ |
2607 | if (i == 1) | |
8ad97cfc | 2608 | new_rtx = XVECEXP (x, 0, 0); |
ede7cd44 | 2609 | else |
09051660 RH |
2610 | { |
2611 | int j; | |
2612 | ||
8ad97cfc KG |
2613 | new_rtx = rtx_alloc (PARALLEL); |
2614 | XVEC (new_rtx, 0) = rtvec_alloc (i); | |
09051660 | 2615 | for (j = i - 1; j >= 0; j--) |
8ad97cfc | 2616 | XVECEXP (new_rtx, 0, j) = XVECEXP (x, 0, j); |
09051660 RH |
2617 | } |
2618 | ||
2619 | /* Recognize it. */ | |
2620 | memset (&clobber_head, 0, sizeof(clobber_head)); | |
8ad97cfc | 2621 | last = add_to_sequence (new_rtx, &clobber_head, "", type, 1); |
ede7cd44 | 2622 | |
09051660 RH |
2623 | /* Find the end of the test chain on the last node. */ |
2624 | for (test = last->tests; test->next; test = test->next) | |
2625 | continue; | |
2626 | ||
2627 | /* We definitely have a new test to add -- create a new | |
2628 | node if needed. */ | |
2629 | place = &test->next; | |
2630 | if (test->type == DT_accept_op) | |
2631 | { | |
2632 | last = new_decision ("", &last->success); | |
2633 | place = &last->tests; | |
2634 | } | |
2635 | ||
2199e5fa ZW |
2636 | /* Skip the C test if it's known to be true at compile |
2637 | time. */ | |
2638 | if (truth == -1) | |
09051660 RH |
2639 | { |
2640 | test = new_decision_test (DT_c_test, &place); | |
2641 | test->u.c_test = c_test; | |
2642 | } | |
2643 | ||
2644 | test = new_decision_test (DT_accept_insn, &place); | |
2645 | test->u.insn.code_number = next_insn_code; | |
bcdaba58 | 2646 | test->u.insn.lineno = pattern_lineno; |
09051660 RH |
2647 | test->u.insn.num_clobbers_to_add = XVECLEN (x, 0) - i; |
2648 | ||
2649 | merge_trees (&head, &clobber_head); | |
ede7cd44 | 2650 | } |
ede7cd44 | 2651 | } |
09051660 RH |
2652 | break; |
2653 | ||
2654 | case SPLIT: | |
2655 | /* Define the subroutine we will call below and emit in genemit. */ | |
a406f566 | 2656 | printf ("extern rtx gen_split_%d (rtx, rtx *);\n", next_insn_code); |
09051660 RH |
2657 | break; |
2658 | ||
2659 | case PEEPHOLE2: | |
2660 | /* Define the subroutine we will call below and emit in genemit. */ | |
3d7aafde | 2661 | printf ("extern rtx gen_peephole2_%d (rtx, rtx *);\n", |
09051660 RH |
2662 | next_insn_code); |
2663 | break; | |
ec65fa66 | 2664 | } |
e0689256 | 2665 | |
09051660 | 2666 | return head; |
ec65fa66 RK |
2667 | } |
2668 | ||
09051660 | 2669 | static void |
3d7aafde | 2670 | process_tree (struct decision_head *head, enum routine_type subroutine_type) |
ec65fa66 | 2671 | { |
4dc320a5 RH |
2672 | if (head->first == NULL) |
2673 | { | |
2674 | /* We can elide peephole2_insns, but not recog or split_insns. */ | |
2675 | if (subroutine_type == PEEPHOLE2) | |
2676 | return; | |
2677 | } | |
2678 | else | |
e8f9b13a RH |
2679 | { |
2680 | factor_tests (head); | |
ec65fa66 | 2681 | |
e8f9b13a RH |
2682 | next_subroutine_number = 0; |
2683 | break_out_subroutines (head, 1); | |
2684 | find_afterward (head, NULL); | |
c1b59dce | 2685 | |
4dc320a5 RH |
2686 | /* We run this after find_afterward, because find_afterward needs |
2687 | the redundant DT_mode tests on predicates to determine whether | |
2688 | two tests can both be true or not. */ | |
2689 | simplify_tests(head); | |
2690 | ||
e8f9b13a RH |
2691 | write_subroutines (head, subroutine_type); |
2692 | } | |
4dc320a5 | 2693 | |
09051660 RH |
2694 | write_subroutine (head, subroutine_type); |
2695 | } | |
2696 | \f | |
3d7aafde | 2697 | extern int main (int, char **); |
36f0e0a6 | 2698 | |
ec65fa66 | 2699 | int |
3d7aafde | 2700 | main (int argc, char **argv) |
ec65fa66 RK |
2701 | { |
2702 | rtx desc; | |
09051660 | 2703 | struct decision_head recog_tree, split_tree, peephole2_tree, h; |
ec65fa66 | 2704 | |
f8b6598e | 2705 | progname = "genrecog"; |
09051660 RH |
2706 | |
2707 | memset (&recog_tree, 0, sizeof recog_tree); | |
2708 | memset (&split_tree, 0, sizeof split_tree); | |
2709 | memset (&peephole2_tree, 0, sizeof peephole2_tree); | |
ec65fa66 | 2710 | |
04d8aa70 | 2711 | if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) |
c88c0d42 | 2712 | return (FATAL_EXIT_CODE); |
ec65fa66 | 2713 | |
ec65fa66 | 2714 | next_insn_code = 0; |
ec65fa66 | 2715 | |
09051660 | 2716 | write_header (); |
ec65fa66 RK |
2717 | |
2718 | /* Read the machine description. */ | |
2719 | ||
2720 | while (1) | |
2721 | { | |
c88c0d42 CP |
2722 | desc = read_md_rtx (&pattern_lineno, &next_insn_code); |
2723 | if (desc == NULL) | |
ec65fa66 | 2724 | break; |
ec65fa66 | 2725 | |
e543e219 | 2726 | switch (GET_CODE (desc)) |
09051660 | 2727 | { |
e543e219 ZW |
2728 | case DEFINE_PREDICATE: |
2729 | case DEFINE_SPECIAL_PREDICATE: | |
2730 | process_define_predicate (desc); | |
2731 | break; | |
2732 | ||
2733 | case DEFINE_INSN: | |
09051660 RH |
2734 | h = make_insn_sequence (desc, RECOG); |
2735 | merge_trees (&recog_tree, &h); | |
e543e219 ZW |
2736 | break; |
2737 | ||
2738 | case DEFINE_SPLIT: | |
09051660 RH |
2739 | h = make_insn_sequence (desc, SPLIT); |
2740 | merge_trees (&split_tree, &h); | |
e543e219 ZW |
2741 | break; |
2742 | ||
2743 | case DEFINE_PEEPHOLE2: | |
09051660 RH |
2744 | h = make_insn_sequence (desc, PEEPHOLE2); |
2745 | merge_trees (&peephole2_tree, &h); | |
5b7c7046 | 2746 | |
e543e219 ZW |
2747 | default: |
2748 | /* do nothing */; | |
2749 | } | |
ec65fa66 RK |
2750 | } |
2751 | ||
bb933490 | 2752 | if (have_error) |
bcdaba58 RH |
2753 | return FATAL_EXIT_CODE; |
2754 | ||
09051660 | 2755 | puts ("\n\n"); |
ec65fa66 | 2756 | |
09051660 RH |
2757 | process_tree (&recog_tree, RECOG); |
2758 | process_tree (&split_tree, SPLIT); | |
2759 | process_tree (&peephole2_tree, PEEPHOLE2); | |
ede7cd44 | 2760 | |
ec65fa66 | 2761 | fflush (stdout); |
c1b59dce | 2762 | return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); |
ec65fa66 | 2763 | } |
09051660 | 2764 | \f |
09051660 | 2765 | static void |
3d7aafde | 2766 | debug_decision_2 (struct decision_test *test) |
09051660 RH |
2767 | { |
2768 | switch (test->type) | |
2769 | { | |
0cd6c85a PB |
2770 | case DT_num_insns: |
2771 | fprintf (stderr, "num_insns=%d", test->u.num_insns); | |
2772 | break; | |
09051660 RH |
2773 | case DT_mode: |
2774 | fprintf (stderr, "mode=%s", GET_MODE_NAME (test->u.mode)); | |
2775 | break; | |
2776 | case DT_code: | |
2777 | fprintf (stderr, "code=%s", GET_RTX_NAME (test->u.code)); | |
2778 | break; | |
2779 | case DT_veclen: | |
2780 | fprintf (stderr, "veclen=%d", test->u.veclen); | |
2781 | break; | |
2782 | case DT_elt_zero_int: | |
2783 | fprintf (stderr, "elt0_i=%d", (int) test->u.intval); | |
2784 | break; | |
2785 | case DT_elt_one_int: | |
2786 | fprintf (stderr, "elt1_i=%d", (int) test->u.intval); | |
2787 | break; | |
2788 | case DT_elt_zero_wide: | |
90ff44cf | 2789 | fprintf (stderr, "elt0_w=" HOST_WIDE_INT_PRINT_DEC, test->u.intval); |
09051660 | 2790 | break; |
070ef6f4 | 2791 | case DT_elt_zero_wide_safe: |
90ff44cf | 2792 | fprintf (stderr, "elt0_ws=" HOST_WIDE_INT_PRINT_DEC, test->u.intval); |
070ef6f4 | 2793 | break; |
521b9224 RH |
2794 | case DT_veclen_ge: |
2795 | fprintf (stderr, "veclen>=%d", test->u.veclen); | |
2796 | break; | |
09051660 RH |
2797 | case DT_dup: |
2798 | fprintf (stderr, "dup=%d", test->u.dup); | |
2799 | break; | |
2800 | case DT_pred: | |
2801 | fprintf (stderr, "pred=(%s,%s)", | |
2802 | test->u.pred.name, GET_MODE_NAME(test->u.pred.mode)); | |
2803 | break; | |
2804 | case DT_c_test: | |
2805 | { | |
2806 | char sub[16+4]; | |
2807 | strncpy (sub, test->u.c_test, sizeof(sub)); | |
2808 | memcpy (sub+16, "...", 4); | |
2809 | fprintf (stderr, "c_test=\"%s\"", sub); | |
2810 | } | |
2811 | break; | |
2812 | case DT_accept_op: | |
2813 | fprintf (stderr, "A_op=%d", test->u.opno); | |
2814 | break; | |
2815 | case DT_accept_insn: | |
5b7c7046 | 2816 | fprintf (stderr, "A_insn=(%d,%d)", |
09051660 RH |
2817 | test->u.insn.code_number, test->u.insn.num_clobbers_to_add); |
2818 | break; | |
2819 | ||
2820 | default: | |
b2d59f6f | 2821 | gcc_unreachable (); |
09051660 RH |
2822 | } |
2823 | } | |
2824 | ||
2825 | static void | |
3d7aafde | 2826 | debug_decision_1 (struct decision *d, int indent) |
09051660 RH |
2827 | { |
2828 | int i; | |
2829 | struct decision_test *test; | |
2830 | ||
2831 | if (d == NULL) | |
2832 | { | |
2833 | for (i = 0; i < indent; ++i) | |
2834 | putc (' ', stderr); | |
2835 | fputs ("(nil)\n", stderr); | |
2836 | return; | |
2837 | } | |
2838 | ||
2839 | for (i = 0; i < indent; ++i) | |
2840 | putc (' ', stderr); | |
2841 | ||
2842 | putc ('{', stderr); | |
2843 | test = d->tests; | |
2844 | if (test) | |
2845 | { | |
2846 | debug_decision_2 (test); | |
2847 | while ((test = test->next) != NULL) | |
2848 | { | |
2849 | fputs (" + ", stderr); | |
2850 | debug_decision_2 (test); | |
2851 | } | |
2852 | } | |
4dc320a5 RH |
2853 | fprintf (stderr, "} %d n %d a %d\n", d->number, |
2854 | (d->next ? d->next->number : -1), | |
2855 | (d->afterward ? d->afterward->number : -1)); | |
09051660 RH |
2856 | } |
2857 | ||
2858 | static void | |
3d7aafde | 2859 | debug_decision_0 (struct decision *d, int indent, int maxdepth) |
09051660 RH |
2860 | { |
2861 | struct decision *n; | |
2862 | int i; | |
2863 | ||
2864 | if (maxdepth < 0) | |
2865 | return; | |
2866 | if (d == NULL) | |
2867 | { | |
2868 | for (i = 0; i < indent; ++i) | |
2869 | putc (' ', stderr); | |
2870 | fputs ("(nil)\n", stderr); | |
2871 | return; | |
2872 | } | |
2873 | ||
2874 | debug_decision_1 (d, indent); | |
2875 | for (n = d->success.first; n ; n = n->next) | |
2876 | debug_decision_0 (n, indent + 2, maxdepth - 1); | |
2877 | } | |
2878 | ||
24e47c76 | 2879 | DEBUG_FUNCTION void |
3d7aafde | 2880 | debug_decision (struct decision *d) |
09051660 RH |
2881 | { |
2882 | debug_decision_0 (d, 0, 1000000); | |
2883 | } | |
ec1c89e6 | 2884 | |
24e47c76 | 2885 | DEBUG_FUNCTION void |
3d7aafde | 2886 | debug_decision_list (struct decision *d) |
ec1c89e6 RH |
2887 | { |
2888 | while (d) | |
2889 | { | |
2890 | debug_decision_0 (d, 0, 0); | |
2891 | d = d->next; | |
2892 | } | |
2893 | } |