Add 2006 to copyright line
[gcc.git] / gcc / genpreds.c
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 Free Software Foundation, Inc.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
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 "gensupport.h"
31 #include "obstack.h"
32
33 /* The new way to declare predicates is with (define_predicate) or
34 (define_special_predicate) expressions in the machine description.
35 This provides a function body as well as a name. */
36 static void
37 process_define_predicate (rtx defn)
38 {
39 struct pred_data *pred;
40 if (XEXP (defn, 1) == 0)
41 {
42 error ("%s: must give a predicate expression", XSTR (defn, 0));
43 return;
44 }
45
46 pred = XCNEW (struct pred_data);
47 pred->name = XSTR (defn, 0);
48 pred->exp = XEXP (defn, 1);
49 pred->c_block = XSTR (defn, 2);
50
51 if (GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
52 pred->special = true;
53
54 add_predicate (pred);
55 }
56
57 /* Write tm-preds.h. Unfortunately, it is impossible to forward-declare
58 an enumeration in portable C, so we have to condition all these
59 prototypes on HAVE_MACHINE_MODES. */
60 static void
61 write_tm_preds_h (void)
62 {
63 struct pred_data *p;
64
65 printf ("\
66 /* Generated automatically by the program '%s'\n\
67 from the machine description file '%s'. */\n\n", progname, in_fname);
68
69 puts ("\
70 #ifndef GCC_TM_PREDS_H\n\
71 #define GCC_TM_PREDS_H\n\
72 \n\
73 #ifdef HAVE_MACHINE_MODES");
74
75 FOR_ALL_PREDICATES (p)
76 printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
77
78 puts ("\
79 #endif /* HAVE_MACHINE_MODES */\n\
80 #endif /* tm-preds.h */");
81 }
82
83 /* Given a predicate, if it has an embedded C block, write the block
84 out as a static inline subroutine, and augment the RTL test with a
85 match_test that calls that subroutine. For instance,
86
87 (define_predicate "basereg_operand"
88 (match_operand 0 "register_operand")
89 {
90 if (GET_CODE (op) == SUBREG)
91 op = SUBREG_REG (op);
92 return REG_POINTER (op);
93 })
94
95 becomes
96
97 static inline int basereg_operand_1(rtx op, enum machine_mode mode)
98 {
99 if (GET_CODE (op) == SUBREG)
100 op = SUBREG_REG (op);
101 return REG_POINTER (op);
102 }
103
104 (define_predicate "basereg_operand"
105 (and (match_operand 0 "register_operand")
106 (match_test "basereg_operand_1 (op, mode)")))
107
108 The only wart is that there's no way to insist on a { } string in
109 an RTL template, so we have to handle "" strings. */
110
111
112 static void
113 write_predicate_subfunction (struct pred_data *p)
114 {
115 const char *match_test_str;
116 rtx match_test_exp, and_exp;
117
118 if (p->c_block[0] == '\0')
119 return;
120
121 /* Construct the function-call expression. */
122 obstack_grow (rtl_obstack, p->name, strlen (p->name));
123 obstack_grow (rtl_obstack, "_1 (op, mode)",
124 sizeof "_1 (op, mode)");
125 match_test_str = XOBFINISH (rtl_obstack, const char *);
126
127 /* Add the function-call expression to the complete expression to be
128 evaluated. */
129 match_test_exp = rtx_alloc (MATCH_TEST);
130 XSTR (match_test_exp, 0) = match_test_str;
131
132 and_exp = rtx_alloc (AND);
133 XEXP (and_exp, 0) = p->exp;
134 XEXP (and_exp, 1) = match_test_exp;
135
136 p->exp = and_exp;
137
138 printf ("static inline int\n"
139 "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n",
140 p->name);
141 print_rtx_ptr_loc (p->c_block);
142 if (p->c_block[0] == '{')
143 fputs (p->c_block, stdout);
144 else
145 printf ("{\n %s\n}", p->c_block);
146 fputs ("\n\n", stdout);
147 }
148
149 /* Given an RTL expression EXP, find all subexpressions which we may
150 assume to perform mode tests. Normal MATCH_OPERAND does;
151 MATCH_CODE does if it applies to the whole expression and accepts
152 CONST_INT or CONST_DOUBLE; and we have to assume that MATCH_TEST
153 does not. These combine in almost-boolean fashion - the only
154 exception is that (not X) must be assumed not to perform a mode
155 test, whether or not X does.
156
157 The mark is the RTL /v flag, which is true for subexpressions which
158 do *not* perform mode tests.
159 */
160 #define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
161 static void
162 mark_mode_tests (rtx exp)
163 {
164 switch (GET_CODE (exp))
165 {
166 case MATCH_OPERAND:
167 {
168 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
169 if (!p)
170 error ("reference to undefined predicate '%s'", XSTR (exp, 1));
171 else if (p->special || GET_MODE (exp) != VOIDmode)
172 NO_MODE_TEST (exp) = 1;
173 }
174 break;
175
176 case MATCH_CODE:
177 if (XSTR (exp, 1)[0] != '\0'
178 || (!strstr (XSTR (exp, 0), "const_int")
179 && !strstr (XSTR (exp, 0), "const_double")))
180 NO_MODE_TEST (exp) = 1;
181 break;
182
183 case MATCH_TEST:
184 case NOT:
185 NO_MODE_TEST (exp) = 1;
186 break;
187
188 case AND:
189 mark_mode_tests (XEXP (exp, 0));
190 mark_mode_tests (XEXP (exp, 1));
191
192 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
193 && NO_MODE_TEST (XEXP (exp, 1)));
194 break;
195
196 case IOR:
197 mark_mode_tests (XEXP (exp, 0));
198 mark_mode_tests (XEXP (exp, 1));
199
200 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
201 || NO_MODE_TEST (XEXP (exp, 1)));
202 break;
203
204 case IF_THEN_ELSE:
205 /* A ? B : C does a mode test if (one of A and B) does a mode
206 test, and C does too. */
207 mark_mode_tests (XEXP (exp, 0));
208 mark_mode_tests (XEXP (exp, 1));
209 mark_mode_tests (XEXP (exp, 2));
210
211 NO_MODE_TEST (exp) = ((NO_MODE_TEST (XEXP (exp, 0))
212 && NO_MODE_TEST (XEXP (exp, 1)))
213 || NO_MODE_TEST (XEXP (exp, 2)));
214 break;
215
216 default:
217 error ("'%s' cannot be used in a define_predicate expression",
218 GET_RTX_NAME (GET_CODE (exp)));
219 }
220 }
221
222 /* Given a predicate, work out where in its RTL expression to add
223 tests for proper modes. Special predicates do not get any such
224 tests. We try to avoid adding tests when we don't have to; in
225 particular, other normal predicates can be counted on to do it for
226 us. */
227
228 static void
229 add_mode_tests (struct pred_data *p)
230 {
231 rtx match_test_exp, and_exp;
232 rtx *pos;
233
234 /* Don't touch special predicates. */
235 if (p->special)
236 return;
237
238 mark_mode_tests (p->exp);
239
240 /* If the whole expression already tests the mode, we're done. */
241 if (!NO_MODE_TEST (p->exp))
242 return;
243
244 match_test_exp = rtx_alloc (MATCH_TEST);
245 XSTR (match_test_exp, 0) = "mode == VOIDmode || GET_MODE (op) == mode";
246 and_exp = rtx_alloc (AND);
247 XEXP (and_exp, 1) = match_test_exp;
248
249 /* It is always correct to rewrite p->exp as
250
251 (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
252
253 but there are a couple forms where we can do better. If the
254 top-level pattern is an IOR, and one of the two branches does test
255 the mode, we can wrap just the branch that doesn't. Likewise, if
256 we have an IF_THEN_ELSE, and one side of it tests the mode, we can
257 wrap just the side that doesn't. And, of course, we can repeat this
258 descent as many times as it works. */
259
260 pos = &p->exp;
261 for (;;)
262 {
263 rtx subexp = *pos;
264
265 switch (GET_CODE (subexp))
266 {
267 case IOR:
268 {
269 int test0 = NO_MODE_TEST (XEXP (subexp, 0));
270 int test1 = NO_MODE_TEST (XEXP (subexp, 1));
271
272 gcc_assert (test0 || test1);
273
274 if (test0 && test1)
275 goto break_loop;
276 pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
277 }
278 break;
279
280 case IF_THEN_ELSE:
281 {
282 int test0 = NO_MODE_TEST (XEXP (subexp, 0));
283 int test1 = NO_MODE_TEST (XEXP (subexp, 1));
284 int test2 = NO_MODE_TEST (XEXP (subexp, 2));
285
286 gcc_assert ((test0 && test1) || test2);
287
288 if (test0 && test1 && test2)
289 goto break_loop;
290 if (test0 && test1)
291 /* Must put it on the dependent clause, not the
292 controlling expression, or we change the meaning of
293 the test. */
294 pos = &XEXP (subexp, 1);
295 else
296 pos = &XEXP (subexp, 2);
297 }
298 break;
299
300 default:
301 goto break_loop;
302 }
303 }
304 break_loop:
305 XEXP (and_exp, 0) = *pos;
306 *pos = and_exp;
307 }
308
309 /* PATH is a string describing a path from the root of an RTL
310 expression to an inner subexpression to be tested. Output
311 code which computes the subexpression from the variable
312 holding the root of the expression. */
313 static void
314 write_extract_subexp (const char *path)
315 {
316 int len = strlen (path);
317 int i;
318
319 /* We first write out the operations (XEXP or XVECEXP) in reverse
320 order, then write "op", then the indices in forward order. */
321 for (i = len - 1; i >= 0; i--)
322 {
323 if (ISLOWER (path[i]))
324 fputs ("XVECEXP (", stdout);
325 else if (ISDIGIT (path[i]))
326 fputs ("XEXP (", stdout);
327 else
328 {
329 error ("bad character in path string '%s'", path);
330 return;
331 }
332 }
333
334 fputs ("op", stdout);
335
336 for (i = 0; i < len; i++)
337 {
338 if (ISLOWER (path[i]))
339 printf (", 0, %d)", path[i] - 'a');
340 else if (ISDIGIT (path[i]))
341 printf (", %d)", path[i] - '0');
342 else
343 gcc_unreachable ();
344 }
345 }
346
347 /* CODES is a list of RTX codes. Write out an expression which
348 determines whether the operand has one of those codes. */
349 static void
350 write_match_code (const char *path, const char *codes)
351 {
352 const char *code;
353
354 while ((code = scan_comma_elt (&codes)) != 0)
355 {
356 fputs ("GET_CODE (", stdout);
357 write_extract_subexp (path);
358 fputs (") == ", stdout);
359 while (code < codes)
360 {
361 putchar (TOUPPER (*code));
362 code++;
363 }
364
365 if (*codes == ',')
366 fputs (" || ", stdout);
367 }
368 }
369
370 /* EXP is an RTL (sub)expression for a predicate. Recursively
371 descend the expression and write out an equivalent C expression. */
372 static void
373 write_predicate_expr (const char *name, rtx exp)
374 {
375 switch (GET_CODE (exp))
376 {
377 case AND:
378 putchar ('(');
379 write_predicate_expr (name, XEXP (exp, 0));
380 fputs (") && (", stdout);
381 write_predicate_expr (name, XEXP (exp, 1));
382 putchar (')');
383 break;
384
385 case IOR:
386 putchar ('(');
387 write_predicate_expr (name, XEXP (exp, 0));
388 fputs (") || (", stdout);
389 write_predicate_expr (name, XEXP (exp, 1));
390 putchar (')');
391 break;
392
393 case NOT:
394 fputs ("!(", stdout);
395 write_predicate_expr (name, XEXP (exp, 0));
396 putchar (')');
397 break;
398
399 case IF_THEN_ELSE:
400 putchar ('(');
401 write_predicate_expr (name, XEXP (exp, 0));
402 fputs (") ? (", stdout);
403 write_predicate_expr (name, XEXP (exp, 1));
404 fputs (") : (", stdout);
405 write_predicate_expr (name, XEXP (exp, 2));
406 putchar (')');
407 break;
408
409 case MATCH_OPERAND:
410 if (GET_MODE (exp) == VOIDmode)
411 printf ("%s (op, mode)", XSTR (exp, 1));
412 else
413 printf ("%s (op, %smode)", XSTR (exp, 1), mode_name[GET_MODE (exp)]);
414 break;
415
416 case MATCH_CODE:
417 write_match_code (XSTR (exp, 1), XSTR (exp, 0));
418 break;
419
420 case MATCH_TEST:
421 print_c_condition (XSTR (exp, 0));
422 break;
423
424 default:
425 error ("%s: cannot use '%s' in a predicate expression",
426 name, GET_RTX_NAME (GET_CODE (exp)));
427 putchar ('0');
428 }
429 }
430
431 /* Given a predicate, write out a complete C function to compute it. */
432 static void
433 write_one_predicate_function (struct pred_data *p)
434 {
435 if (!p->exp)
436 return;
437
438 write_predicate_subfunction (p);
439 add_mode_tests (p);
440
441 /* A normal predicate can legitimately not look at enum machine_mode
442 if it accepts only CONST_INTs and/or CONST_DOUBLEs. */
443 printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n"
444 "{\n return ",
445 p->name);
446 write_predicate_expr (p->name, p->exp);
447 fputs (";\n}\n\n", stdout);
448 }
449
450 /* Write insn-preds.c.
451 N.B. the list of headers to include was copied from genrecog; it
452 may not be ideal.
453
454 FUTURE: Write #line markers referring back to the machine
455 description. (Can't practically do this now since we don't know
456 the line number of the C block - just the line number of the enclosing
457 expression.) */
458 static void
459 write_insn_preds_c (void)
460 {
461 struct pred_data *p;
462
463 printf ("\
464 /* Generated automatically by the program '%s'\n\
465 from the machine description file '%s'. */\n\n", progname, in_fname);
466
467 puts ("\
468 #include \"config.h\"\n\
469 #include \"system.h\"\n\
470 #include \"coretypes.h\"\n\
471 #include \"tm.h\"\n\
472 #include \"rtl.h\"\n\
473 #include \"tree.h\"\n\
474 #include \"tm_p.h\"\n\
475 #include \"function.h\"\n\
476 #include \"insn-config.h\"\n\
477 #include \"recog.h\"\n\
478 #include \"real.h\"\n\
479 #include \"output.h\"\n\
480 #include \"flags.h\"\n\
481 #include \"hard-reg-set.h\"\n\
482 #include \"resource.h\"\n\
483 #include \"toplev.h\"\n\
484 #include \"reload.h\"\n\
485 #include \"regs.h\"\n");
486
487 FOR_ALL_PREDICATES (p)
488 write_one_predicate_function (p);
489 }
490
491 /* Argument parsing. */
492 static bool gen_header;
493 static bool
494 parse_option (const char *opt)
495 {
496 if (!strcmp (opt, "-h"))
497 {
498 gen_header = true;
499 return 1;
500 }
501 else
502 return 0;
503 }
504
505 /* Master control. */
506 int
507 main (int argc, char **argv)
508 {
509 rtx defn;
510 int pattern_lineno, next_insn_code = 0;
511
512 progname = argv[0];
513 if (argc <= 1)
514 fatal ("no input file name");
515 if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
516 return FATAL_EXIT_CODE;
517
518 while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
519 {
520 if (GET_CODE (defn) == DEFINE_PREDICATE
521 || GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
522 process_define_predicate (defn);
523 }
524
525 if (gen_header)
526 write_tm_preds_h ();
527 else
528 write_insn_preds_c ();
529
530 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
531 return FATAL_EXIT_CODE;
532
533 return SUCCESS_EXIT_CODE;
534 }