Dead
[official-gcc.git] / gomp-20050608-branch / gcc / genpreds.c
blobbfd681cc7b8b724091f8e110742e10def3e5d704
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.
7 This file is part of GCC.
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.
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.
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. */
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"
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)
39 struct pred_data *pred;
40 if (XEXP (defn, 1) == 0)
42 error ("%s: must give a predicate expression", XSTR (defn, 0));
43 return;
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);
51 if (GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
52 pred->special = true;
54 add_predicate (pred);
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)
63 struct pred_data *p;
65 printf ("\
66 /* Generated automatically by the program '%s'\n\
67 from the machine description file '%s'. */\n\n", progname, in_fname);
69 puts ("\
70 #ifndef GCC_TM_PREDS_H\n\
71 #define GCC_TM_PREDS_H\n\
72 \n\
73 #ifdef HAVE_MACHINE_MODES");
75 FOR_ALL_PREDICATES (p)
76 printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
78 puts ("\
79 #endif /* HAVE_MACHINE_MODES */\n\
80 #endif /* tm-preds.h */");
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,
87 (define_predicate "basereg_operand"
88 (match_operand 0 "register_operand")
90 if (GET_CODE (op) == SUBREG)
91 op = SUBREG_REG (op);
92 return REG_POINTER (op);
95 becomes
97 static inline int basereg_operand_1(rtx op, enum machine_mode mode)
99 if (GET_CODE (op) == SUBREG)
100 op = SUBREG_REG (op);
101 return REG_POINTER (op);
104 (define_predicate "basereg_operand"
105 (and (match_operand 0 "register_operand")
106 (match_test "basereg_operand_1 (op, mode)")))
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. */
112 static void
113 write_predicate_subfunction (struct pred_data *p)
115 const char *match_test_str;
116 rtx match_test_exp, and_exp;
118 if (p->c_block[0] == '\0')
119 return;
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 *);
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;
132 and_exp = rtx_alloc (AND);
133 XEXP (and_exp, 0) = p->exp;
134 XEXP (and_exp, 1) = match_test_exp;
136 p->exp = and_exp;
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);
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.
157 The mark is the RTL /v flag, which is true for subexpressions which
158 do *not* perform mode tests.
160 #define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
161 static void
162 mark_mode_tests (rtx exp)
164 switch (GET_CODE (exp))
166 case MATCH_OPERAND:
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;
174 break;
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;
183 case MATCH_TEST:
184 case NOT:
185 NO_MODE_TEST (exp) = 1;
186 break;
188 case AND:
189 mark_mode_tests (XEXP (exp, 0));
190 mark_mode_tests (XEXP (exp, 1));
192 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
193 && NO_MODE_TEST (XEXP (exp, 1)));
194 break;
196 case IOR:
197 mark_mode_tests (XEXP (exp, 0));
198 mark_mode_tests (XEXP (exp, 1));
200 NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
201 || NO_MODE_TEST (XEXP (exp, 1)));
202 break;
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));
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;
216 default:
217 error ("'%s' cannot be used in a define_predicate expression",
218 GET_RTX_NAME (GET_CODE (exp)));
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. */
228 static void
229 add_mode_tests (struct pred_data *p)
231 rtx match_test_exp, and_exp;
232 rtx *pos;
234 /* Don't touch special predicates. */
235 if (p->special)
236 return;
238 mark_mode_tests (p->exp);
240 /* If the whole expression already tests the mode, we're done. */
241 if (!NO_MODE_TEST (p->exp))
242 return;
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;
249 /* It is always correct to rewrite p->exp as
251 (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
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. */
260 pos = &p->exp;
261 for (;;)
263 rtx subexp = *pos;
265 switch (GET_CODE (subexp))
267 case IOR:
269 int test0 = NO_MODE_TEST (XEXP (subexp, 0));
270 int test1 = NO_MODE_TEST (XEXP (subexp, 1));
272 gcc_assert (test0 || test1);
274 if (test0 && test1)
275 goto break_loop;
276 pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
278 break;
280 case IF_THEN_ELSE:
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));
286 gcc_assert ((test0 && test1) || test2);
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);
298 break;
300 default:
301 goto break_loop;
304 break_loop:
305 XEXP (and_exp, 0) = *pos;
306 *pos = and_exp;
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)
316 int len = strlen (path);
317 int i;
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--)
323 if (ISLOWER (path[i]))
324 fputs ("XVECEXP (", stdout);
325 else if (ISDIGIT (path[i]))
326 fputs ("XEXP (", stdout);
327 else
329 error ("bad character in path string '%s'", path);
330 return;
334 fputs ("op", stdout);
336 for (i = 0; i < len; i++)
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 ();
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)
352 const char *code;
354 while ((code = scan_comma_elt (&codes)) != 0)
356 fputs ("GET_CODE (", stdout);
357 write_extract_subexp (path);
358 fputs (") == ", stdout);
359 while (code < codes)
361 putchar (TOUPPER (*code));
362 code++;
365 if (*codes == ',')
366 fputs (" || ", stdout);
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)
375 switch (GET_CODE (exp))
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;
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;
393 case NOT:
394 fputs ("!(", stdout);
395 write_predicate_expr (name, XEXP (exp, 0));
396 putchar (')');
397 break;
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;
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;
416 case MATCH_CODE:
417 write_match_code (XSTR (exp, 1), XSTR (exp, 0));
418 break;
420 case MATCH_TEST:
421 print_c_condition (XSTR (exp, 0));
422 break;
424 default:
425 error ("%s: cannot use '%s' in a predicate expression",
426 name, GET_RTX_NAME (GET_CODE (exp)));
427 putchar ('0');
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)
435 if (!p->exp)
436 return;
438 write_predicate_subfunction (p);
439 add_mode_tests (p);
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);
450 /* Write insn-preds.c.
451 N.B. the list of headers to include was copied from genrecog; it
452 may not be ideal.
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)
461 struct pred_data *p;
463 printf ("\
464 /* Generated automatically by the program '%s'\n\
465 from the machine description file '%s'. */\n\n", progname, in_fname);
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");
487 FOR_ALL_PREDICATES (p)
488 write_one_predicate_function (p);
491 /* Argument parsing. */
492 static bool gen_header;
493 static bool
494 parse_option (const char *opt)
496 if (!strcmp (opt, "-h"))
498 gen_header = true;
499 return 1;
501 else
502 return 0;
505 /* Master control. */
507 main (int argc, char **argv)
509 rtx defn;
510 int pattern_lineno, next_insn_code = 0;
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;
518 while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
520 if (GET_CODE (defn) == DEFINE_PREDICATE
521 || GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
522 process_define_predicate (defn);
525 if (gen_header)
526 write_tm_preds_h ();
527 else
528 write_insn_preds_c ();
530 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
531 return FATAL_EXIT_CODE;
533 return SUCCESS_EXIT_CODE;