0
|
1 /* Generate from machine description:
|
|
2 - prototype declarations for operand predicates (tm-preds.h)
|
|
3 - function definitions of operand predicates, if defined new-style
|
|
4 (insn-preds.c)
|
|
5 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
|
|
6 Free Software Foundation, Inc.
|
|
7
|
|
8 This file is part of GCC.
|
|
9
|
|
10 GCC is free software; you can redistribute it and/or modify
|
|
11 it under the terms of the GNU General Public License as published by
|
|
12 the Free Software Foundation; either version 3, or (at your option)
|
|
13 any later version.
|
|
14
|
|
15 GCC is distributed in the hope that it will be useful,
|
|
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
18 GNU General Public License for more details.
|
|
19
|
|
20 You should have received a copy of the GNU General Public License
|
|
21 along with GCC; see the file COPYING3. If not see
|
|
22 <http://www.gnu.org/licenses/>. */
|
|
23
|
|
24 #include "bconfig.h"
|
|
25 #include "system.h"
|
|
26 #include "coretypes.h"
|
|
27 #include "tm.h"
|
|
28 #include "rtl.h"
|
|
29 #include "errors.h"
|
|
30 #include "obstack.h"
|
|
31 #include "gensupport.h"
|
|
32
|
|
33 /* Given a predicate expression EXP, from form NAME at line LINENO,
|
|
34 verify that it does not contain any RTL constructs which are not
|
|
35 valid in predicate definitions. Returns true if EXP is
|
|
36 INvalid; issues error messages, caller need not. */
|
|
37 static bool
|
|
38 validate_exp (rtx exp, const char *name, int lineno)
|
|
39 {
|
|
40 if (exp == 0)
|
|
41 {
|
|
42 message_with_line (lineno, "%s: must give a predicate expression", name);
|
|
43 return true;
|
|
44 }
|
|
45
|
|
46 switch (GET_CODE (exp))
|
|
47 {
|
|
48 /* Ternary, binary, unary expressions: recurse into subexpressions. */
|
|
49 case IF_THEN_ELSE:
|
|
50 if (validate_exp (XEXP (exp, 2), name, lineno))
|
|
51 return true;
|
|
52 /* else fall through */
|
|
53 case AND:
|
|
54 case IOR:
|
|
55 if (validate_exp (XEXP (exp, 1), name, lineno))
|
|
56 return true;
|
|
57 /* else fall through */
|
|
58 case NOT:
|
|
59 return validate_exp (XEXP (exp, 0), name, lineno);
|
|
60
|
|
61 /* MATCH_CODE might have a syntax error in its path expression. */
|
|
62 case MATCH_CODE:
|
|
63 {
|
|
64 const char *p;
|
|
65 for (p = XSTR (exp, 1); *p; p++)
|
|
66 {
|
|
67 if (!ISDIGIT (*p) && !ISLOWER (*p))
|
|
68 {
|
|
69 message_with_line (lineno, "%s: invalid character in path "
|
|
70 "string '%s'", name, XSTR (exp, 1));
|
|
71 have_error = 1;
|
|
72 return true;
|
|
73 }
|
|
74 }
|
|
75 }
|
|
76 /* fall through */
|
|
77
|
|
78 /* These need no special checking. */
|
|
79 case MATCH_OPERAND:
|
|
80 case MATCH_TEST:
|
|
81 return false;
|
|
82
|
|
83 default:
|
|
84 message_with_line (lineno,
|
|
85 "%s: cannot use '%s' in a predicate expression",
|
|
86 name, GET_RTX_NAME (GET_CODE (exp)));
|
|
87 have_error = 1;
|
|
88 return true;
|
|
89 }
|
|
90 }
|
|
91
|
|
92 /* Predicates are defined with (define_predicate) or
|
|
93 (define_special_predicate) expressions in the machine description. */
|
|
94 static void
|
|
95 process_define_predicate (rtx defn, int lineno)
|
|
96 {
|
|
97 struct pred_data *pred;
|
|
98 const char *p;
|
|
99
|
|
100 if (!ISALPHA (XSTR (defn, 0)[0]) && XSTR (defn, 0)[0] != '_')
|
|
101 goto bad_name;
|
|
102 for (p = XSTR (defn, 0) + 1; *p; p++)
|
|
103 if (!ISALNUM (*p) && *p != '_')
|
|
104 goto bad_name;
|
|
105
|
|
106 if (validate_exp (XEXP (defn, 1), XSTR (defn, 0), lineno))
|
|
107 return;
|
|
108
|
|
109 pred = XCNEW (struct pred_data);
|
|
110 pred->name = XSTR (defn, 0);
|
|
111 pred->exp = XEXP (defn, 1);
|
|
112 pred->c_block = XSTR (defn, 2);
|
|
113
|
|
114 if (GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
|
|
115 pred->special = true;
|
|
116
|
|
117 add_predicate (pred);
|
|
118 return;
|
|
119
|
|
120 bad_name:
|
|
121 message_with_line (lineno,
|
|
122 "%s: predicate name must be a valid C function name",
|
|
123 XSTR (defn, 0));
|
|
124 have_error = 1;
|
|
125 return;
|
|
126 }
|
|
127
|
|
128 /* Given a predicate, if it has an embedded C block, write the block
|
|
129 out as a static inline subroutine, and augment the RTL test with a
|
|
130 match_test that calls that subroutine. For instance,
|
|
131
|
|
132 (define_predicate "basereg_operand"
|
|
133 (match_operand 0 "register_operand")
|
|
134 {
|
|
135 if (GET_CODE (op) == SUBREG)
|
|
136 op = SUBREG_REG (op);
|
|
137 return REG_POINTER (op);
|
|
138 })
|
|
139
|
|
140 becomes
|
|
141
|
|
142 static inline int basereg_operand_1(rtx op, enum machine_mode mode)
|
|
143 {
|
|
144 if (GET_CODE (op) == SUBREG)
|
|
145 op = SUBREG_REG (op);
|
|
146 return REG_POINTER (op);
|
|
147 }
|
|
148
|
|
149 (define_predicate "basereg_operand"
|
|
150 (and (match_operand 0 "register_operand")
|
|
151 (match_test "basereg_operand_1 (op, mode)")))
|
|
152
|
|
153 The only wart is that there's no way to insist on a { } string in
|
|
154 an RTL template, so we have to handle "" strings. */
|
|
155
|
|
156
|
|
157 static void
|
|
158 write_predicate_subfunction (struct pred_data *p)
|
|
159 {
|
|
160 const char *match_test_str;
|
|
161 rtx match_test_exp, and_exp;
|
|
162
|
|
163 if (p->c_block[0] == '\0')
|
|
164 return;
|
|
165
|
|
166 /* Construct the function-call expression. */
|
|
167 obstack_grow (rtl_obstack, p->name, strlen (p->name));
|
|
168 obstack_grow (rtl_obstack, "_1 (op, mode)",
|
|
169 sizeof "_1 (op, mode)");
|
|
170 match_test_str = XOBFINISH (rtl_obstack, const char *);
|
|
171
|
|
172 /* Add the function-call expression to the complete expression to be
|
|
173 evaluated. */
|
|
174 match_test_exp = rtx_alloc (MATCH_TEST);
|
|
175 XSTR (match_test_exp, 0) = match_test_str;
|
|
176
|
|
177 and_exp = rtx_alloc (AND);
|
|
178 XEXP (and_exp, 0) = p->exp;
|
|
179 XEXP (and_exp, 1) = match_test_exp;
|
|
180
|
|
181 p->exp = and_exp;
|
|
182
|
|
183 printf ("static inline int\n"
|
|
184 "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n",
|
|
185 p->name);
|
|
186 print_rtx_ptr_loc (p->c_block);
|
|
187 if (p->c_block[0] == '{')
|
|
188 fputs (p->c_block, stdout);
|
|
189 else
|
|
190 printf ("{\n %s\n}", p->c_block);
|
|
191 fputs ("\n\n", stdout);
|
|
192 }
|
|
193
|
|
194 /* Given a predicate expression EXP, from form NAME, determine whether
|
|
195 it refers to the variable given as VAR. */
|
|
196 static bool
|
|
197 needs_variable (rtx exp, const char *var)
|
|
198 {
|
|
199 switch (GET_CODE (exp))
|
|
200 {
|
|
201 /* Ternary, binary, unary expressions need a variable if
|
|
202 any of their subexpressions do. */
|
|
203 case IF_THEN_ELSE:
|
|
204 if (needs_variable (XEXP (exp, 2), var))
|
|
205 return true;
|
|
206 /* else fall through */
|
|
207 case AND:
|
|
208 case IOR:
|
|
209 if (needs_variable (XEXP (exp, 1), var))
|
|
210 return true;
|
|
211 /* else fall through */
|
|
212 case NOT:
|
|
213 return needs_variable (XEXP (exp, 0), var);
|
|
214
|
|
215 /* MATCH_CODE uses "op", but nothing else. */
|
|
216 case MATCH_CODE:
|
|
217 return !strcmp (var, "op");
|
|
218
|
|
219 /* MATCH_OPERAND uses "op" and may use "mode". */
|
|
220 case MATCH_OPERAND:
|
|
221 if (!strcmp (var, "op"))
|
|
222 return true;
|
|
223 if (!strcmp (var, "mode") && GET_MODE (exp) == VOIDmode)
|
|
224 return true;
|
|
225 return false;
|
|
226
|
|
227 /* MATCH_TEST uses var if XSTR (exp, 0) =~ /\b${var}\b/o; */
|
|
228 case MATCH_TEST:
|
|
229 {
|
|
230 const char *p = XSTR (exp, 0);
|
|
231 const char *q = strstr (p, var);
|
|
232 if (!q)
|
|
233 return false;
|
|
234 if (q != p && (ISALNUM (q[-1]) || q[-1] == '_'))
|
|
235 return false;
|
|
236 q += strlen (var);
|
|
237 if (ISALNUM (q[0]) || q[0] == '_')
|
|
238 return false;
|
|
239 }
|
|
240 return true;
|
|
241
|
|
242 default:
|
|
243 gcc_unreachable ();
|
|
244 }
|
|
245 }
|
|
246
|
|
247 /* Given an RTL expression EXP, find all subexpressions which we may
|
|
248 assume to perform mode tests. Normal MATCH_OPERAND does;
|
|
249 MATCH_CODE does if it applies to the whole expression and accepts
|
|
250 CONST_INT or CONST_DOUBLE; and we have to assume that MATCH_TEST
|
|
251 does not. These combine in almost-boolean fashion - the only
|
|
252 exception is that (not X) must be assumed not to perform a mode
|
|
253 test, whether or not X does.
|
|
254
|
|
255 The mark is the RTL /v flag, which is true for subexpressions which
|
|
256 do *not* perform mode tests.
|
|
257 */
|
|
258 #define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
|
|
259 static void
|
|
260 mark_mode_tests (rtx exp)
|
|
261 {
|
|
262 switch (GET_CODE (exp))
|
|
263 {
|
|
264 case MATCH_OPERAND:
|
|
265 {
|
|
266 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
|
|
267 if (!p)
|
|
268 error ("reference to undefined predicate '%s'", XSTR (exp, 1));
|
|
269 else if (p->special || GET_MODE (exp) != VOIDmode)
|
|
270 NO_MODE_TEST (exp) = 1;
|
|
271 }
|
|
272 break;
|
|
273
|
|
274 case MATCH_CODE:
|
|
275 if (XSTR (exp, 1)[0] != '\0'
|
|
276 || (!strstr (XSTR (exp, 0), "const_int")
|
|
277 && !strstr (XSTR (exp, 0), "const_double")))
|
|
278 NO_MODE_TEST (exp) = 1;
|
|
279 break;
|
|
280
|
|
281 case MATCH_TEST:
|
|
282 case NOT:
|
|
283 NO_MODE_TEST (exp) = 1;
|
|
284 break;
|
|
285
|
|
286 case AND:
|
|
287 mark_mode_tests (XEXP (exp, 0));
|
|
288 mark_mode_tests (XEXP (exp, 1));
|
|
289
|
|
290 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
|
|
291 && NO_MODE_TEST (XEXP (exp, 1)));
|
|
292 break;
|
|
293
|
|
294 case IOR:
|
|
295 mark_mode_tests (XEXP (exp, 0));
|
|
296 mark_mode_tests (XEXP (exp, 1));
|
|
297
|
|
298 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
|
|
299 || NO_MODE_TEST (XEXP (exp, 1)));
|
|
300 break;
|
|
301
|
|
302 case IF_THEN_ELSE:
|
|
303 /* A ? B : C does a mode test if (one of A and B) does a mode
|
|
304 test, and C does too. */
|
|
305 mark_mode_tests (XEXP (exp, 0));
|
|
306 mark_mode_tests (XEXP (exp, 1));
|
|
307 mark_mode_tests (XEXP (exp, 2));
|
|
308
|
|
309 NO_MODE_TEST (exp) = ((NO_MODE_TEST (XEXP (exp, 0))
|
|
310 && NO_MODE_TEST (XEXP (exp, 1)))
|
|
311 || NO_MODE_TEST (XEXP (exp, 2)));
|
|
312 break;
|
|
313
|
|
314 default:
|
|
315 gcc_unreachable ();
|
|
316 }
|
|
317 }
|
|
318
|
|
319 /* Determine whether the expression EXP is a MATCH_CODE that should
|
|
320 be written as a switch statement. */
|
|
321 static bool
|
|
322 generate_switch_p (rtx exp)
|
|
323 {
|
|
324 return GET_CODE (exp) == MATCH_CODE
|
|
325 && strchr (XSTR (exp, 0), ',');
|
|
326 }
|
|
327
|
|
328 /* Given a predicate, work out where in its RTL expression to add
|
|
329 tests for proper modes. Special predicates do not get any such
|
|
330 tests. We try to avoid adding tests when we don't have to; in
|
|
331 particular, other normal predicates can be counted on to do it for
|
|
332 us. */
|
|
333
|
|
334 static void
|
|
335 add_mode_tests (struct pred_data *p)
|
|
336 {
|
|
337 rtx match_test_exp, and_exp;
|
|
338 rtx *pos;
|
|
339
|
|
340 /* Don't touch special predicates. */
|
|
341 if (p->special)
|
|
342 return;
|
|
343
|
|
344 mark_mode_tests (p->exp);
|
|
345
|
|
346 /* If the whole expression already tests the mode, we're done. */
|
|
347 if (!NO_MODE_TEST (p->exp))
|
|
348 return;
|
|
349
|
|
350 match_test_exp = rtx_alloc (MATCH_TEST);
|
|
351 XSTR (match_test_exp, 0) = "mode == VOIDmode || GET_MODE (op) == mode";
|
|
352 and_exp = rtx_alloc (AND);
|
|
353 XEXP (and_exp, 1) = match_test_exp;
|
|
354
|
|
355 /* It is always correct to rewrite p->exp as
|
|
356
|
|
357 (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
|
|
358
|
|
359 but there are a couple forms where we can do better. If the
|
|
360 top-level pattern is an IOR, and one of the two branches does test
|
|
361 the mode, we can wrap just the branch that doesn't. Likewise, if
|
|
362 we have an IF_THEN_ELSE, and one side of it tests the mode, we can
|
|
363 wrap just the side that doesn't. And, of course, we can repeat this
|
|
364 descent as many times as it works. */
|
|
365
|
|
366 pos = &p->exp;
|
|
367 for (;;)
|
|
368 {
|
|
369 rtx subexp = *pos;
|
|
370
|
|
371 switch (GET_CODE (subexp))
|
|
372 {
|
|
373 case AND:
|
|
374 /* The switch code generation in write_predicate_stmts prefers
|
|
375 rtx code tests to be at the top of the expression tree. So
|
|
376 push this AND down into the second operand of an existing
|
|
377 AND expression. */
|
|
378 if (generate_switch_p (XEXP (subexp, 0)))
|
|
379 pos = &XEXP (subexp, 1);
|
|
380 goto break_loop;
|
|
381
|
|
382 case IOR:
|
|
383 {
|
|
384 int test0 = NO_MODE_TEST (XEXP (subexp, 0));
|
|
385 int test1 = NO_MODE_TEST (XEXP (subexp, 1));
|
|
386
|
|
387 gcc_assert (test0 || test1);
|
|
388
|
|
389 if (test0 && test1)
|
|
390 goto break_loop;
|
|
391 pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
|
|
392 }
|
|
393 break;
|
|
394
|
|
395 case IF_THEN_ELSE:
|
|
396 {
|
|
397 int test0 = NO_MODE_TEST (XEXP (subexp, 0));
|
|
398 int test1 = NO_MODE_TEST (XEXP (subexp, 1));
|
|
399 int test2 = NO_MODE_TEST (XEXP (subexp, 2));
|
|
400
|
|
401 gcc_assert ((test0 && test1) || test2);
|
|
402
|
|
403 if (test0 && test1 && test2)
|
|
404 goto break_loop;
|
|
405 if (test0 && test1)
|
|
406 /* Must put it on the dependent clause, not the
|
|
407 controlling expression, or we change the meaning of
|
|
408 the test. */
|
|
409 pos = &XEXP (subexp, 1);
|
|
410 else
|
|
411 pos = &XEXP (subexp, 2);
|
|
412 }
|
|
413 break;
|
|
414
|
|
415 default:
|
|
416 goto break_loop;
|
|
417 }
|
|
418 }
|
|
419 break_loop:
|
|
420 XEXP (and_exp, 0) = *pos;
|
|
421 *pos = and_exp;
|
|
422 }
|
|
423
|
|
424 /* PATH is a string describing a path from the root of an RTL
|
|
425 expression to an inner subexpression to be tested. Output
|
|
426 code which computes the subexpression from the variable
|
|
427 holding the root of the expression. */
|
|
428 static void
|
|
429 write_extract_subexp (const char *path)
|
|
430 {
|
|
431 int len = strlen (path);
|
|
432 int i;
|
|
433
|
|
434 /* We first write out the operations (XEXP or XVECEXP) in reverse
|
|
435 order, then write "op", then the indices in forward order. */
|
|
436 for (i = len - 1; i >= 0; i--)
|
|
437 {
|
|
438 if (ISLOWER (path[i]))
|
|
439 fputs ("XVECEXP (", stdout);
|
|
440 else if (ISDIGIT (path[i]))
|
|
441 fputs ("XEXP (", stdout);
|
|
442 else
|
|
443 gcc_unreachable ();
|
|
444 }
|
|
445
|
|
446 fputs ("op", stdout);
|
|
447
|
|
448 for (i = 0; i < len; i++)
|
|
449 {
|
|
450 if (ISLOWER (path[i]))
|
|
451 printf (", 0, %d)", path[i] - 'a');
|
|
452 else if (ISDIGIT (path[i]))
|
|
453 printf (", %d)", path[i] - '0');
|
|
454 else
|
|
455 gcc_unreachable ();
|
|
456 }
|
|
457 }
|
|
458
|
|
459 /* CODES is a list of RTX codes. Write out an expression which
|
|
460 determines whether the operand has one of those codes. */
|
|
461 static void
|
|
462 write_match_code (const char *path, const char *codes)
|
|
463 {
|
|
464 const char *code;
|
|
465
|
|
466 while ((code = scan_comma_elt (&codes)) != 0)
|
|
467 {
|
|
468 fputs ("GET_CODE (", stdout);
|
|
469 write_extract_subexp (path);
|
|
470 fputs (") == ", stdout);
|
|
471 while (code < codes)
|
|
472 {
|
|
473 putchar (TOUPPER (*code));
|
|
474 code++;
|
|
475 }
|
|
476
|
|
477 if (*codes == ',')
|
|
478 fputs (" || ", stdout);
|
|
479 }
|
|
480 }
|
|
481
|
|
482 /* EXP is an RTL (sub)expression for a predicate. Recursively
|
|
483 descend the expression and write out an equivalent C expression. */
|
|
484 static void
|
|
485 write_predicate_expr (rtx exp)
|
|
486 {
|
|
487 switch (GET_CODE (exp))
|
|
488 {
|
|
489 case AND:
|
|
490 putchar ('(');
|
|
491 write_predicate_expr (XEXP (exp, 0));
|
|
492 fputs (") && (", stdout);
|
|
493 write_predicate_expr (XEXP (exp, 1));
|
|
494 putchar (')');
|
|
495 break;
|
|
496
|
|
497 case IOR:
|
|
498 putchar ('(');
|
|
499 write_predicate_expr (XEXP (exp, 0));
|
|
500 fputs (") || (", stdout);
|
|
501 write_predicate_expr (XEXP (exp, 1));
|
|
502 putchar (')');
|
|
503 break;
|
|
504
|
|
505 case NOT:
|
|
506 fputs ("!(", stdout);
|
|
507 write_predicate_expr (XEXP (exp, 0));
|
|
508 putchar (')');
|
|
509 break;
|
|
510
|
|
511 case IF_THEN_ELSE:
|
|
512 putchar ('(');
|
|
513 write_predicate_expr (XEXP (exp, 0));
|
|
514 fputs (") ? (", stdout);
|
|
515 write_predicate_expr (XEXP (exp, 1));
|
|
516 fputs (") : (", stdout);
|
|
517 write_predicate_expr (XEXP (exp, 2));
|
|
518 putchar (')');
|
|
519 break;
|
|
520
|
|
521 case MATCH_OPERAND:
|
|
522 if (GET_MODE (exp) == VOIDmode)
|
|
523 printf ("%s (op, mode)", XSTR (exp, 1));
|
|
524 else
|
|
525 printf ("%s (op, %smode)", XSTR (exp, 1), mode_name[GET_MODE (exp)]);
|
|
526 break;
|
|
527
|
|
528 case MATCH_CODE:
|
|
529 write_match_code (XSTR (exp, 1), XSTR (exp, 0));
|
|
530 break;
|
|
531
|
|
532 case MATCH_TEST:
|
|
533 print_c_condition (XSTR (exp, 0));
|
|
534 break;
|
|
535
|
|
536 default:
|
|
537 gcc_unreachable ();
|
|
538 }
|
|
539 }
|
|
540
|
|
541 /* Write the MATCH_CODE expression EXP as a switch statement. */
|
|
542
|
|
543 static void
|
|
544 write_match_code_switch (rtx exp)
|
|
545 {
|
|
546 const char *codes = XSTR (exp, 0);
|
|
547 const char *path = XSTR (exp, 1);
|
|
548 const char *code;
|
|
549
|
|
550 fputs (" switch (GET_CODE (", stdout);
|
|
551 write_extract_subexp (path);
|
|
552 fputs ("))\n {\n", stdout);
|
|
553
|
|
554 while ((code = scan_comma_elt (&codes)) != 0)
|
|
555 {
|
|
556 fputs (" case ", stdout);
|
|
557 while (code < codes)
|
|
558 {
|
|
559 putchar (TOUPPER (*code));
|
|
560 code++;
|
|
561 }
|
|
562 fputs(":\n", stdout);
|
|
563 }
|
|
564 }
|
|
565
|
|
566 /* Given a predicate expression EXP, write out a sequence of stmts
|
|
567 to evaluate it. This is similar to write_predicate_expr but can
|
|
568 generate efficient switch statements. */
|
|
569
|
|
570 static void
|
|
571 write_predicate_stmts (rtx exp)
|
|
572 {
|
|
573 switch (GET_CODE (exp))
|
|
574 {
|
|
575 case MATCH_CODE:
|
|
576 if (generate_switch_p (exp))
|
|
577 {
|
|
578 write_match_code_switch (exp);
|
|
579 puts (" return true;\n"
|
|
580 " default:\n"
|
|
581 " break;\n"
|
|
582 " }\n"
|
|
583 " return false;");
|
|
584 return;
|
|
585 }
|
|
586 break;
|
|
587
|
|
588 case AND:
|
|
589 if (generate_switch_p (XEXP (exp, 0)))
|
|
590 {
|
|
591 write_match_code_switch (XEXP (exp, 0));
|
|
592 puts (" break;\n"
|
|
593 " default:\n"
|
|
594 " return false;\n"
|
|
595 " }");
|
|
596 exp = XEXP (exp, 1);
|
|
597 }
|
|
598 break;
|
|
599
|
|
600 case IOR:
|
|
601 if (generate_switch_p (XEXP (exp, 0)))
|
|
602 {
|
|
603 write_match_code_switch (XEXP (exp, 0));
|
|
604 puts (" return true;\n"
|
|
605 " default:\n"
|
|
606 " break;\n"
|
|
607 " }");
|
|
608 exp = XEXP (exp, 1);
|
|
609 }
|
|
610 break;
|
|
611
|
|
612 case NOT:
|
|
613 if (generate_switch_p (XEXP (exp, 0)))
|
|
614 {
|
|
615 write_match_code_switch (XEXP (exp, 0));
|
|
616 puts (" return false;\n"
|
|
617 " default:\n"
|
|
618 " break;\n"
|
|
619 " }\n"
|
|
620 " return true;");
|
|
621 return;
|
|
622 }
|
|
623 break;
|
|
624
|
|
625 default:
|
|
626 break;
|
|
627 }
|
|
628
|
|
629 fputs(" return ",stdout);
|
|
630 write_predicate_expr (exp);
|
|
631 fputs(";\n", stdout);
|
|
632 }
|
|
633
|
|
634 /* Given a predicate, write out a complete C function to compute it. */
|
|
635 static void
|
|
636 write_one_predicate_function (struct pred_data *p)
|
|
637 {
|
|
638 if (!p->exp)
|
|
639 return;
|
|
640
|
|
641 write_predicate_subfunction (p);
|
|
642 add_mode_tests (p);
|
|
643
|
|
644 /* A normal predicate can legitimately not look at enum machine_mode
|
|
645 if it accepts only CONST_INTs and/or CONST_DOUBLEs. */
|
|
646 printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
|
|
647 p->name);
|
|
648 write_predicate_stmts (p->exp);
|
|
649 fputs ("}\n\n", stdout);
|
|
650 }
|
|
651
|
|
652 /* Constraints fall into two categories: register constraints
|
|
653 (define_register_constraint), and others (define_constraint,
|
|
654 define_memory_constraint, define_address_constraint). We
|
|
655 work out automatically which of the various old-style macros
|
|
656 they correspond to, and produce appropriate code. They all
|
|
657 go in the same hash table so we can verify that there are no
|
|
658 duplicate names. */
|
|
659
|
|
660 /* All data from one constraint definition. */
|
|
661 struct constraint_data
|
|
662 {
|
|
663 struct constraint_data *next_this_letter;
|
|
664 struct constraint_data *next_textual;
|
|
665 const char *name;
|
|
666 const char *c_name; /* same as .name unless mangling is necessary */
|
|
667 size_t namelen;
|
|
668 const char *regclass; /* for register constraints */
|
|
669 rtx exp; /* for other constraints */
|
|
670 unsigned int lineno; /* line of definition */
|
|
671 unsigned int is_register : 1;
|
|
672 unsigned int is_const_int : 1;
|
|
673 unsigned int is_const_dbl : 1;
|
|
674 unsigned int is_extra : 1;
|
|
675 unsigned int is_memory : 1;
|
|
676 unsigned int is_address : 1;
|
|
677 };
|
|
678
|
|
679 /* Overview of all constraints beginning with a given letter. */
|
|
680
|
|
681 static struct constraint_data *
|
|
682 constraints_by_letter_table[1<<CHAR_BIT];
|
|
683
|
|
684 /* For looking up all the constraints in the order that they appeared
|
|
685 in the machine description. */
|
|
686 static struct constraint_data *first_constraint;
|
|
687 static struct constraint_data **last_constraint_ptr = &first_constraint;
|
|
688
|
|
689 #define FOR_ALL_CONSTRAINTS(iter_) \
|
|
690 for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
|
|
691
|
|
692 /* These letters, and all names beginning with them, are reserved for
|
|
693 generic constraints.
|
|
694 The 'm' constraint is not mentioned here since that constraint
|
|
695 letter can be overridden by the back end by defining the
|
|
696 TARGET_MEM_CONSTRAINT macro. */
|
|
697 static const char generic_constraint_letters[] = "EFVXginoprs";
|
|
698
|
|
699 /* Machine-independent code expects that constraints with these
|
|
700 (initial) letters will allow only (a subset of all) CONST_INTs. */
|
|
701
|
|
702 static const char const_int_constraints[] = "IJKLMNOP";
|
|
703
|
|
704 /* Machine-independent code expects that constraints with these
|
|
705 (initial) letters will allow only (a subset of all) CONST_DOUBLEs. */
|
|
706
|
|
707 static const char const_dbl_constraints[] = "GH";
|
|
708
|
|
709 /* Summary data used to decide whether to output various functions and
|
|
710 macro definitions. */
|
|
711 static unsigned int constraint_max_namelen;
|
|
712 static bool have_register_constraints;
|
|
713 static bool have_memory_constraints;
|
|
714 static bool have_address_constraints;
|
|
715 static bool have_extra_constraints;
|
|
716 static bool have_const_int_constraints;
|
|
717 static bool have_const_dbl_constraints;
|
|
718
|
|
719 /* Convert NAME, which contains angle brackets and/or underscores, to
|
|
720 a string that can be used as part of a C identifier. The string
|
|
721 comes from the rtl_obstack. */
|
|
722 static const char *
|
|
723 mangle (const char *name)
|
|
724 {
|
|
725 for (; *name; name++)
|
|
726 switch (*name)
|
|
727 {
|
|
728 case '_': obstack_grow (rtl_obstack, "__", 2); break;
|
|
729 case '<': obstack_grow (rtl_obstack, "_l", 2); break;
|
|
730 case '>': obstack_grow (rtl_obstack, "_g", 2); break;
|
|
731 default: obstack_1grow (rtl_obstack, *name); break;
|
|
732 }
|
|
733
|
|
734 obstack_1grow (rtl_obstack, '\0');
|
|
735 return XOBFINISH (rtl_obstack, const char *);
|
|
736 }
|
|
737
|
|
738 /* Add one constraint, of any sort, to the tables. NAME is its name;
|
|
739 REGCLASS is the register class, if any; EXP is the expression to
|
|
740 test, if any; IS_MEMORY and IS_ADDRESS indicate memory and address
|
|
741 constraints, respectively; LINENO is the line number from the MD reader.
|
|
742 Not all combinations of arguments are valid; most importantly, REGCLASS
|
|
743 is mutually exclusive with EXP, and IS_MEMORY/IS_ADDRESS are only
|
|
744 meaningful for constraints with EXP.
|
|
745
|
|
746 This function enforces all syntactic and semantic rules about what
|
|
747 constraints can be defined. */
|
|
748
|
|
749 static void
|
|
750 add_constraint (const char *name, const char *regclass,
|
|
751 rtx exp, bool is_memory, bool is_address,
|
|
752 int lineno)
|
|
753 {
|
|
754 struct constraint_data *c, **iter, **slot;
|
|
755 const char *p;
|
|
756 bool need_mangled_name = false;
|
|
757 bool is_const_int;
|
|
758 bool is_const_dbl;
|
|
759 size_t namelen;
|
|
760
|
|
761 if (exp && validate_exp (exp, name, lineno))
|
|
762 return;
|
|
763
|
|
764 if (!ISALPHA (name[0]) && name[0] != '_')
|
|
765 {
|
|
766 if (name[1] == '\0')
|
|
767 message_with_line (lineno, "constraint name '%s' is not "
|
|
768 "a letter or underscore", name);
|
|
769 else
|
|
770 message_with_line (lineno, "constraint name '%s' does not begin "
|
|
771 "with a letter or underscore", name);
|
|
772 have_error = 1;
|
|
773 return;
|
|
774 }
|
|
775 for (p = name; *p; p++)
|
|
776 if (!ISALNUM (*p))
|
|
777 {
|
|
778 if (*p == '<' || *p == '>' || *p == '_')
|
|
779 need_mangled_name = true;
|
|
780 else
|
|
781 {
|
|
782 message_with_line (lineno,
|
|
783 "constraint name '%s' must be composed of "
|
|
784 "letters, digits, underscores, and "
|
|
785 "angle brackets", name);
|
|
786 have_error = 1;
|
|
787 return;
|
|
788 }
|
|
789 }
|
|
790
|
|
791 if (strchr (generic_constraint_letters, name[0]))
|
|
792 {
|
|
793 if (name[1] == '\0')
|
|
794 message_with_line (lineno, "constraint letter '%s' cannot be "
|
|
795 "redefined by the machine description", name);
|
|
796 else
|
|
797 message_with_line (lineno, "constraint name '%s' cannot be defined by "
|
|
798 "the machine description, as it begins with '%c'",
|
|
799 name, name[0]);
|
|
800 have_error = 1;
|
|
801 return;
|
|
802 }
|
|
803
|
|
804
|
|
805 namelen = strlen (name);
|
|
806 slot = &constraints_by_letter_table[(unsigned int)name[0]];
|
|
807 for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
|
|
808 {
|
|
809 /* This causes slot to end up pointing to the
|
|
810 next_this_letter field of the last constraint with a name
|
|
811 of equal or greater length than the new constraint; hence
|
|
812 the new constraint will be inserted after all previous
|
|
813 constraints with names of the same length. */
|
|
814 if ((*iter)->namelen >= namelen)
|
|
815 slot = iter;
|
|
816
|
|
817 if (!strcmp ((*iter)->name, name))
|
|
818 {
|
|
819 message_with_line (lineno, "redefinition of constraint '%s'", name);
|
|
820 message_with_line ((*iter)->lineno, "previous definition is here");
|
|
821 have_error = 1;
|
|
822 return;
|
|
823 }
|
|
824 else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
|
|
825 {
|
|
826 message_with_line (lineno, "defining constraint '%s' here", name);
|
|
827 message_with_line ((*iter)->lineno, "renders constraint '%s' "
|
|
828 "(defined here) a prefix", (*iter)->name);
|
|
829 have_error = 1;
|
|
830 return;
|
|
831 }
|
|
832 else if (!strncmp ((*iter)->name, name, namelen))
|
|
833 {
|
|
834 message_with_line (lineno, "constraint '%s' is a prefix", name);
|
|
835 message_with_line ((*iter)->lineno, "of constraint '%s' "
|
|
836 "(defined here)", (*iter)->name);
|
|
837 have_error = 1;
|
|
838 return;
|
|
839 }
|
|
840 }
|
|
841
|
|
842 is_const_int = strchr (const_int_constraints, name[0]) != 0;
|
|
843 is_const_dbl = strchr (const_dbl_constraints, name[0]) != 0;
|
|
844
|
|
845 if (is_const_int || is_const_dbl)
|
|
846 {
|
|
847 enum rtx_code appropriate_code
|
|
848 = is_const_int ? CONST_INT : CONST_DOUBLE;
|
|
849
|
|
850 /* Consider relaxing this requirement in the future. */
|
|
851 if (regclass
|
|
852 || GET_CODE (exp) != AND
|
|
853 || GET_CODE (XEXP (exp, 0)) != MATCH_CODE
|
|
854 || strcmp (XSTR (XEXP (exp, 0), 0),
|
|
855 GET_RTX_NAME (appropriate_code)))
|
|
856 {
|
|
857 if (name[1] == '\0')
|
|
858 message_with_line (lineno, "constraint letter '%c' is reserved "
|
|
859 "for %s constraints",
|
|
860 name[0], GET_RTX_NAME (appropriate_code));
|
|
861 else
|
|
862 message_with_line (lineno, "constraint names beginning with '%c' "
|
|
863 "(%s) are reserved for %s constraints",
|
|
864 name[0], name,
|
|
865 GET_RTX_NAME (appropriate_code));
|
|
866
|
|
867 have_error = 1;
|
|
868 return;
|
|
869 }
|
|
870
|
|
871 if (is_memory)
|
|
872 {
|
|
873 if (name[1] == '\0')
|
|
874 message_with_line (lineno, "constraint letter '%c' cannot be a "
|
|
875 "memory constraint", name[0]);
|
|
876 else
|
|
877 message_with_line (lineno, "constraint name '%s' begins with '%c', "
|
|
878 "and therefore cannot be a memory constraint",
|
|
879 name, name[0]);
|
|
880
|
|
881 have_error = 1;
|
|
882 return;
|
|
883 }
|
|
884 else if (is_address)
|
|
885 {
|
|
886 if (name[1] == '\0')
|
|
887 message_with_line (lineno, "constraint letter '%c' cannot be a "
|
|
888 "memory constraint", name[0]);
|
|
889 else
|
|
890 message_with_line (lineno, "constraint name '%s' begins with '%c', "
|
|
891 "and therefore cannot be a memory constraint",
|
|
892 name, name[0]);
|
|
893
|
|
894 have_error = 1;
|
|
895 return;
|
|
896 }
|
|
897 }
|
|
898
|
|
899
|
|
900 c = XOBNEW (rtl_obstack, struct constraint_data);
|
|
901 c->name = name;
|
|
902 c->c_name = need_mangled_name ? mangle (name) : name;
|
|
903 c->lineno = lineno;
|
|
904 c->namelen = namelen;
|
|
905 c->regclass = regclass;
|
|
906 c->exp = exp;
|
|
907 c->is_register = regclass != 0;
|
|
908 c->is_const_int = is_const_int;
|
|
909 c->is_const_dbl = is_const_dbl;
|
|
910 c->is_extra = !(regclass || is_const_int || is_const_dbl);
|
|
911 c->is_memory = is_memory;
|
|
912 c->is_address = is_address;
|
|
913
|
|
914 c->next_this_letter = *slot;
|
|
915 *slot = c;
|
|
916
|
|
917 /* Insert this constraint in the list of all constraints in textual
|
|
918 order. */
|
|
919 c->next_textual = 0;
|
|
920 *last_constraint_ptr = c;
|
|
921 last_constraint_ptr = &c->next_textual;
|
|
922
|
|
923 constraint_max_namelen = MAX (constraint_max_namelen, strlen (name));
|
|
924 have_register_constraints |= c->is_register;
|
|
925 have_const_int_constraints |= c->is_const_int;
|
|
926 have_const_dbl_constraints |= c->is_const_dbl;
|
|
927 have_extra_constraints |= c->is_extra;
|
|
928 have_memory_constraints |= c->is_memory;
|
|
929 have_address_constraints |= c->is_address;
|
|
930 }
|
|
931
|
|
932 /* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
|
|
933 DEFINE_ADDRESS_CONSTRAINT expression, C. */
|
|
934 static void
|
|
935 process_define_constraint (rtx c, int lineno)
|
|
936 {
|
|
937 add_constraint (XSTR (c, 0), 0, XEXP (c, 2),
|
|
938 GET_CODE (c) == DEFINE_MEMORY_CONSTRAINT,
|
|
939 GET_CODE (c) == DEFINE_ADDRESS_CONSTRAINT,
|
|
940 lineno);
|
|
941 }
|
|
942
|
|
943 /* Process a DEFINE_REGISTER_CONSTRAINT expression, C. */
|
|
944 static void
|
|
945 process_define_register_constraint (rtx c, int lineno)
|
|
946 {
|
|
947 add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false, lineno);
|
|
948 }
|
|
949
|
|
950 /* Write out an enumeration with one entry per machine-specific
|
|
951 constraint. */
|
|
952 static void
|
|
953 write_enum_constraint_num (void)
|
|
954 {
|
|
955 struct constraint_data *c;
|
|
956
|
|
957 fputs ("enum constraint_num\n"
|
|
958 "{\n"
|
|
959 " CONSTRAINT__UNKNOWN = 0", stdout);
|
|
960 FOR_ALL_CONSTRAINTS (c)
|
|
961 printf (",\n CONSTRAINT_%s", c->c_name);
|
|
962 puts (",\n CONSTRAINT__LIMIT\n};\n");
|
|
963 }
|
|
964
|
|
965 /* Write out a function which looks at a string and determines what
|
|
966 constraint name, if any, it begins with. */
|
|
967 static void
|
|
968 write_lookup_constraint (void)
|
|
969 {
|
|
970 unsigned int i;
|
|
971 puts ("enum constraint_num\n"
|
|
972 "lookup_constraint (const char *str)\n"
|
|
973 "{\n"
|
|
974 " switch (str[0])\n"
|
|
975 " {");
|
|
976
|
|
977 for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
|
|
978 {
|
|
979 struct constraint_data *c = constraints_by_letter_table[i];
|
|
980 if (!c)
|
|
981 continue;
|
|
982
|
|
983 printf (" case '%c':\n", i);
|
|
984 if (c->namelen == 1)
|
|
985 printf (" return CONSTRAINT_%s;\n", c->c_name);
|
|
986 else
|
|
987 {
|
|
988 do
|
|
989 {
|
|
990 printf (" if (!strncmp (str, \"%s\", %lu))\n"
|
|
991 " return CONSTRAINT_%s;\n",
|
|
992 c->name, (unsigned long int) c->namelen, c->c_name);
|
|
993 c = c->next_this_letter;
|
|
994 }
|
|
995 while (c);
|
|
996 puts (" break;");
|
|
997 }
|
|
998 }
|
|
999
|
|
1000 puts (" default: break;\n"
|
|
1001 " }\n"
|
|
1002 " return CONSTRAINT__UNKNOWN;\n"
|
|
1003 "}\n");
|
|
1004 }
|
|
1005
|
|
1006 /* Write out a function which looks at a string and determines what
|
|
1007 the constraint name length is. */
|
|
1008 static void
|
|
1009 write_insn_constraint_len (void)
|
|
1010 {
|
|
1011 unsigned int i;
|
|
1012
|
|
1013 puts ("static inline size_t\n"
|
|
1014 "insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)\n"
|
|
1015 "{\n"
|
|
1016 " switch (fc)\n"
|
|
1017 " {");
|
|
1018
|
|
1019 for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
|
|
1020 {
|
|
1021 struct constraint_data *c = constraints_by_letter_table[i];
|
|
1022
|
|
1023 if (!c
|
|
1024 || c->namelen == 1)
|
|
1025 continue;
|
|
1026
|
|
1027 /* Constraints with multiple characters should have the same
|
|
1028 length. */
|
|
1029 {
|
|
1030 struct constraint_data *c2 = c->next_this_letter;
|
|
1031 size_t len = c->namelen;
|
|
1032 while (c2)
|
|
1033 {
|
|
1034 if (c2->namelen != len)
|
|
1035 error ("Multi-letter constraints with first letter '%c' "
|
|
1036 "should have same length", i);
|
|
1037 c2 = c2->next_this_letter;
|
|
1038 }
|
|
1039 }
|
|
1040
|
|
1041 printf (" case '%c': return %lu;\n",
|
|
1042 i, (unsigned long int) c->namelen);
|
|
1043 }
|
|
1044
|
|
1045 puts (" default: break;\n"
|
|
1046 " }\n"
|
|
1047 " return 1;\n"
|
|
1048 "}\n");
|
|
1049 }
|
|
1050
|
|
1051 /* Write out the function which computes the register class corresponding
|
|
1052 to a register constraint. */
|
|
1053 static void
|
|
1054 write_regclass_for_constraint (void)
|
|
1055 {
|
|
1056 struct constraint_data *c;
|
|
1057
|
|
1058 puts ("enum reg_class\n"
|
|
1059 "regclass_for_constraint (enum constraint_num c)\n"
|
|
1060 "{\n"
|
|
1061 " switch (c)\n"
|
|
1062 " {");
|
|
1063
|
|
1064 FOR_ALL_CONSTRAINTS (c)
|
|
1065 if (c->is_register)
|
|
1066 printf (" case CONSTRAINT_%s: return %s;\n", c->c_name, c->regclass);
|
|
1067
|
|
1068 puts (" default: break;\n"
|
|
1069 " }\n"
|
|
1070 " return NO_REGS;\n"
|
|
1071 "}\n");
|
|
1072 }
|
|
1073
|
|
1074 /* Write out the functions which compute whether a given value matches
|
|
1075 a given non-register constraint. */
|
|
1076 static void
|
|
1077 write_tm_constrs_h (void)
|
|
1078 {
|
|
1079 struct constraint_data *c;
|
|
1080
|
|
1081 printf ("\
|
|
1082 /* Generated automatically by the program '%s'\n\
|
|
1083 from the machine description file '%s'. */\n\n", progname, in_fname);
|
|
1084
|
|
1085 puts ("\
|
|
1086 #ifndef GCC_TM_CONSTRS_H\n\
|
|
1087 #define GCC_TM_CONSTRS_H\n");
|
|
1088
|
|
1089 FOR_ALL_CONSTRAINTS (c)
|
|
1090 if (!c->is_register)
|
|
1091 {
|
|
1092 bool needs_ival = needs_variable (c->exp, "ival");
|
|
1093 bool needs_hval = needs_variable (c->exp, "hval");
|
|
1094 bool needs_lval = needs_variable (c->exp, "lval");
|
|
1095 bool needs_rval = needs_variable (c->exp, "rval");
|
|
1096 bool needs_mode = (needs_variable (c->exp, "mode")
|
|
1097 || needs_hval || needs_lval || needs_rval);
|
|
1098 bool needs_op = (needs_variable (c->exp, "op")
|
|
1099 || needs_ival || needs_mode);
|
|
1100
|
|
1101 printf ("static inline bool\n"
|
|
1102 "satisfies_constraint_%s (rtx %s)\n"
|
|
1103 "{\n", c->c_name,
|
|
1104 needs_op ? "op" : "ARG_UNUSED (op)");
|
|
1105 if (needs_mode)
|
|
1106 puts (" enum machine_mode mode = GET_MODE (op);");
|
|
1107 if (needs_ival)
|
|
1108 puts (" HOST_WIDE_INT ival = 0;");
|
|
1109 if (needs_hval)
|
|
1110 puts (" HOST_WIDE_INT hval = 0;");
|
|
1111 if (needs_lval)
|
|
1112 puts (" unsigned HOST_WIDE_INT lval = 0;");
|
|
1113 if (needs_rval)
|
|
1114 puts (" const REAL_VALUE_TYPE *rval = 0;");
|
|
1115
|
|
1116 if (needs_ival)
|
|
1117 puts (" if (GET_CODE (op) == CONST_INT)\n"
|
|
1118 " ival = INTVAL (op);");
|
|
1119 if (needs_hval)
|
|
1120 puts (" if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
|
|
1121 " hval = CONST_DOUBLE_HIGH (op);");
|
|
1122 if (needs_lval)
|
|
1123 puts (" if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
|
|
1124 " lval = CONST_DOUBLE_LOW (op);");
|
|
1125 if (needs_rval)
|
|
1126 puts (" if (GET_CODE (op) == CONST_DOUBLE && mode != VOIDmode)"
|
|
1127 " rval = CONST_DOUBLE_REAL_VALUE (op);");
|
|
1128
|
|
1129 write_predicate_stmts (c->exp);
|
|
1130 fputs ("}\n", stdout);
|
|
1131 }
|
|
1132 puts ("#endif /* tm-constrs.h */");
|
|
1133 }
|
|
1134
|
|
1135 /* Write out the wrapper function, constraint_satisfied_p, that maps
|
|
1136 a CONSTRAINT_xxx constant to one of the predicate functions generated
|
|
1137 above. */
|
|
1138 static void
|
|
1139 write_constraint_satisfied_p (void)
|
|
1140 {
|
|
1141 struct constraint_data *c;
|
|
1142
|
|
1143 puts ("bool\n"
|
|
1144 "constraint_satisfied_p (rtx op, enum constraint_num c)\n"
|
|
1145 "{\n"
|
|
1146 " switch (c)\n"
|
|
1147 " {");
|
|
1148
|
|
1149 FOR_ALL_CONSTRAINTS (c)
|
|
1150 if (!c->is_register)
|
|
1151 printf (" case CONSTRAINT_%s: "
|
|
1152 "return satisfies_constraint_%s (op);\n",
|
|
1153 c->c_name, c->c_name);
|
|
1154
|
|
1155 puts (" default: break;\n"
|
|
1156 " }\n"
|
|
1157 " return false;\n"
|
|
1158 "}\n");
|
|
1159 }
|
|
1160
|
|
1161 /* Write out the function which computes whether a given value matches
|
|
1162 a given CONST_INT constraint. This doesn't just forward to
|
|
1163 constraint_satisfied_p because caller passes the INTVAL, not the RTX. */
|
|
1164 static void
|
|
1165 write_insn_const_int_ok_for_constraint (void)
|
|
1166 {
|
|
1167 struct constraint_data *c;
|
|
1168
|
|
1169 puts ("bool\n"
|
|
1170 "insn_const_int_ok_for_constraint (HOST_WIDE_INT ival, "
|
|
1171 "enum constraint_num c)\n"
|
|
1172 "{\n"
|
|
1173 " switch (c)\n"
|
|
1174 " {");
|
|
1175
|
|
1176 FOR_ALL_CONSTRAINTS (c)
|
|
1177 if (c->is_const_int)
|
|
1178 {
|
|
1179 printf (" case CONSTRAINT_%s:\n return ", c->c_name);
|
|
1180 /* c->exp is guaranteed to be (and (match_code "const_int") (...));
|
|
1181 we know at this point that we have a const_int, so we need not
|
|
1182 bother with that part of the test. */
|
|
1183 write_predicate_expr (XEXP (c->exp, 1));
|
|
1184 fputs (";\n\n", stdout);
|
|
1185 }
|
|
1186
|
|
1187 puts (" default: break;\n"
|
|
1188 " }\n"
|
|
1189 " return false;\n"
|
|
1190 "}\n");
|
|
1191 }
|
|
1192
|
|
1193
|
|
1194 /* Write out the function which computes whether a given constraint is
|
|
1195 a memory constraint. */
|
|
1196 static void
|
|
1197 write_insn_extra_memory_constraint (void)
|
|
1198 {
|
|
1199 struct constraint_data *c;
|
|
1200
|
|
1201 puts ("bool\n"
|
|
1202 "insn_extra_memory_constraint (enum constraint_num c)\n"
|
|
1203 "{\n"
|
|
1204 " switch (c)\n"
|
|
1205 " {");
|
|
1206
|
|
1207 FOR_ALL_CONSTRAINTS (c)
|
|
1208 if (c->is_memory)
|
|
1209 printf (" case CONSTRAINT_%s:\n return true;\n\n", c->c_name);
|
|
1210
|
|
1211 puts (" default: break;\n"
|
|
1212 " }\n"
|
|
1213 " return false;\n"
|
|
1214 "}\n");
|
|
1215 }
|
|
1216
|
|
1217 /* Write out the function which computes whether a given constraint is
|
|
1218 an address constraint. */
|
|
1219 static void
|
|
1220 write_insn_extra_address_constraint (void)
|
|
1221 {
|
|
1222 struct constraint_data *c;
|
|
1223
|
|
1224 puts ("bool\n"
|
|
1225 "insn_extra_address_constraint (enum constraint_num c)\n"
|
|
1226 "{\n"
|
|
1227 " switch (c)\n"
|
|
1228 " {");
|
|
1229
|
|
1230 FOR_ALL_CONSTRAINTS (c)
|
|
1231 if (c->is_address)
|
|
1232 printf (" case CONSTRAINT_%s:\n return true;\n\n", c->c_name);
|
|
1233
|
|
1234 puts (" default: break;\n"
|
|
1235 " }\n"
|
|
1236 " return false;\n"
|
|
1237 "}\n");
|
|
1238 }
|
|
1239
|
|
1240
|
|
1241 /* Write tm-preds.h. Unfortunately, it is impossible to forward-declare
|
|
1242 an enumeration in portable C, so we have to condition all these
|
|
1243 prototypes on HAVE_MACHINE_MODES. */
|
|
1244 static void
|
|
1245 write_tm_preds_h (void)
|
|
1246 {
|
|
1247 struct pred_data *p;
|
|
1248
|
|
1249 printf ("\
|
|
1250 /* Generated automatically by the program '%s'\n\
|
|
1251 from the machine description file '%s'. */\n\n", progname, in_fname);
|
|
1252
|
|
1253 puts ("\
|
|
1254 #ifndef GCC_TM_PREDS_H\n\
|
|
1255 #define GCC_TM_PREDS_H\n\
|
|
1256 \n\
|
|
1257 #ifdef HAVE_MACHINE_MODES");
|
|
1258
|
|
1259 FOR_ALL_PREDICATES (p)
|
|
1260 printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
|
|
1261
|
|
1262 puts ("#endif /* HAVE_MACHINE_MODES */\n");
|
|
1263
|
|
1264 if (constraint_max_namelen > 0)
|
|
1265 {
|
|
1266 write_enum_constraint_num ();
|
|
1267 puts ("extern enum constraint_num lookup_constraint (const char *);\n"
|
|
1268 "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
|
|
1269
|
|
1270 if (constraint_max_namelen > 1)
|
|
1271 {
|
|
1272 write_insn_constraint_len ();
|
|
1273 puts ("#define CONSTRAINT_LEN(c_,s_) "
|
|
1274 "insn_constraint_len (c_,s_)\n");
|
|
1275 }
|
|
1276 else
|
|
1277 puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
|
|
1278 if (have_register_constraints)
|
|
1279 puts ("extern enum reg_class regclass_for_constraint "
|
|
1280 "(enum constraint_num);\n"
|
|
1281 "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
|
|
1282 " regclass_for_constraint (lookup_constraint (s_))\n");
|
|
1283 else
|
|
1284 puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS");
|
|
1285 if (have_const_int_constraints)
|
|
1286 puts ("extern bool insn_const_int_ok_for_constraint "
|
|
1287 "(HOST_WIDE_INT, enum constraint_num);\n"
|
|
1288 "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
|
|
1289 " insn_const_int_ok_for_constraint (v_, "
|
|
1290 "lookup_constraint (s_))\n");
|
|
1291 if (have_const_dbl_constraints)
|
|
1292 puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
|
|
1293 " constraint_satisfied_p (v_, lookup_constraint (s_))\n");
|
|
1294 else
|
|
1295 puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n");
|
|
1296 if (have_extra_constraints)
|
|
1297 puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n"
|
|
1298 " constraint_satisfied_p (v_, lookup_constraint (s_))\n");
|
|
1299 if (have_memory_constraints)
|
|
1300 puts ("extern bool "
|
|
1301 "insn_extra_memory_constraint (enum constraint_num);\n"
|
|
1302 "#define EXTRA_MEMORY_CONSTRAINT(c_,s_) "
|
|
1303 "insn_extra_memory_constraint (lookup_constraint (s_))\n");
|
|
1304 else
|
|
1305 puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n");
|
|
1306 if (have_address_constraints)
|
|
1307 puts ("extern bool "
|
|
1308 "insn_extra_address_constraint (enum constraint_num);\n"
|
|
1309 "#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) "
|
|
1310 "insn_extra_address_constraint (lookup_constraint (s_))\n");
|
|
1311 else
|
|
1312 puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
|
|
1313 }
|
|
1314
|
|
1315 puts ("#endif /* tm-preds.h */");
|
|
1316 }
|
|
1317
|
|
1318 /* Write insn-preds.c.
|
|
1319 N.B. the list of headers to include was copied from genrecog; it
|
|
1320 may not be ideal.
|
|
1321
|
|
1322 FUTURE: Write #line markers referring back to the machine
|
|
1323 description. (Can't practically do this now since we don't know
|
|
1324 the line number of the C block - just the line number of the enclosing
|
|
1325 expression.) */
|
|
1326 static void
|
|
1327 write_insn_preds_c (void)
|
|
1328 {
|
|
1329 struct pred_data *p;
|
|
1330
|
|
1331 printf ("\
|
|
1332 /* Generated automatically by the program '%s'\n\
|
|
1333 from the machine description file '%s'. */\n\n", progname, in_fname);
|
|
1334
|
|
1335 puts ("\
|
|
1336 #include \"config.h\"\n\
|
|
1337 #include \"system.h\"\n\
|
|
1338 #include \"coretypes.h\"\n\
|
|
1339 #include \"tm.h\"\n\
|
|
1340 #include \"rtl.h\"\n\
|
|
1341 #include \"tree.h\"\n\
|
|
1342 #include \"tm_p.h\"\n\
|
|
1343 #include \"function.h\"\n\
|
|
1344 #include \"insn-config.h\"\n\
|
|
1345 #include \"recog.h\"\n\
|
|
1346 #include \"real.h\"\n\
|
|
1347 #include \"output.h\"\n\
|
|
1348 #include \"flags.h\"\n\
|
|
1349 #include \"hard-reg-set.h\"\n\
|
|
1350 #include \"resource.h\"\n\
|
|
1351 #include \"toplev.h\"\n\
|
|
1352 #include \"reload.h\"\n\
|
|
1353 #include \"regs.h\"\n\
|
|
1354 #include \"tm-constrs.h\"\n");
|
|
1355
|
|
1356 FOR_ALL_PREDICATES (p)
|
|
1357 write_one_predicate_function (p);
|
|
1358
|
|
1359 if (constraint_max_namelen > 0)
|
|
1360 {
|
|
1361 write_lookup_constraint ();
|
|
1362 if (have_register_constraints)
|
|
1363 write_regclass_for_constraint ();
|
|
1364 write_constraint_satisfied_p ();
|
|
1365
|
|
1366 if (have_const_int_constraints)
|
|
1367 write_insn_const_int_ok_for_constraint ();
|
|
1368
|
|
1369 if (have_memory_constraints)
|
|
1370 write_insn_extra_memory_constraint ();
|
|
1371 if (have_address_constraints)
|
|
1372 write_insn_extra_address_constraint ();
|
|
1373 }
|
|
1374 }
|
|
1375
|
|
1376 /* Argument parsing. */
|
|
1377 static bool gen_header;
|
|
1378 static bool gen_constrs;
|
|
1379
|
|
1380 static bool
|
|
1381 parse_option (const char *opt)
|
|
1382 {
|
|
1383 if (!strcmp (opt, "-h"))
|
|
1384 {
|
|
1385 gen_header = true;
|
|
1386 return 1;
|
|
1387 }
|
|
1388 else if (!strcmp (opt, "-c"))
|
|
1389 {
|
|
1390 gen_constrs = true;
|
|
1391 return 1;
|
|
1392 }
|
|
1393 else
|
|
1394 return 0;
|
|
1395 }
|
|
1396
|
|
1397 /* Master control. */
|
|
1398 int
|
|
1399 main (int argc, char **argv)
|
|
1400 {
|
|
1401 rtx defn;
|
|
1402 int pattern_lineno, next_insn_code = 0;
|
|
1403
|
|
1404 progname = argv[0];
|
|
1405 if (argc <= 1)
|
|
1406 fatal ("no input file name");
|
|
1407 if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
|
|
1408 return FATAL_EXIT_CODE;
|
|
1409
|
|
1410 while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
|
|
1411 switch (GET_CODE (defn))
|
|
1412 {
|
|
1413 case DEFINE_PREDICATE:
|
|
1414 case DEFINE_SPECIAL_PREDICATE:
|
|
1415 process_define_predicate (defn, pattern_lineno);
|
|
1416 break;
|
|
1417
|
|
1418 case DEFINE_CONSTRAINT:
|
|
1419 case DEFINE_MEMORY_CONSTRAINT:
|
|
1420 case DEFINE_ADDRESS_CONSTRAINT:
|
|
1421 process_define_constraint (defn, pattern_lineno);
|
|
1422 break;
|
|
1423
|
|
1424 case DEFINE_REGISTER_CONSTRAINT:
|
|
1425 process_define_register_constraint (defn, pattern_lineno);
|
|
1426 break;
|
|
1427
|
|
1428 default:
|
|
1429 break;
|
|
1430 }
|
|
1431
|
|
1432 if (gen_header)
|
|
1433 write_tm_preds_h ();
|
|
1434 else if (gen_constrs)
|
|
1435 write_tm_constrs_h ();
|
|
1436 else
|
|
1437 write_insn_preds_c ();
|
|
1438
|
|
1439 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
|
|
1440 return FATAL_EXIT_CODE;
|
|
1441
|
|
1442 return SUCCESS_EXIT_CODE;
|
|
1443 }
|