Import of virgin gcc 4.0.0 distribution.
[dragonfly.git] / contrib / gcc-4.0 / 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, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, 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 = xcalloc (sizeof (struct pred_data), 1);
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 = obstack_finish (rtl_obstack);
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   if (p->c_block[0] == '{')
142     fputs (p->c_block, stdout);
143   else
144     printf ("{\n  %s\n}", p->c_block);
145   fputs ("\n\n", stdout);
146 }
147
148 /* Given an RTL expression EXP, find all subexpressions which we may
149    assume to perform mode tests.  Normal MATCH_OPERAND does;
150    MATCH_CODE does if and only if it accepts CONST_INT or
151    CONST_DOUBLE; and we have to assume that MATCH_TEST does not.
152    These combine in almost-boolean fashion - the only exception is
153    that (not X) must be assumed not to perform a mode test, whether or
154    not X does.
155
156    The mark is the RTL /v flag, which is true for subexpressions which
157    do *not* perform mode tests.
158 */
159 #define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
160 static void
161 mark_mode_tests (rtx exp)
162 {
163   switch (GET_CODE (exp))
164     {
165     case MATCH_OPERAND:
166       {
167         struct pred_data *p = lookup_predicate (XSTR (exp, 1));
168         if (!p)
169           error ("reference to undefined predicate '%s'", XSTR (exp, 1));
170         else if (p->special || GET_MODE (exp) != VOIDmode)
171           NO_MODE_TEST (exp) = 1;
172       }
173       break;
174
175     case MATCH_CODE:
176       if (!strstr (XSTR (exp, 0), "const_int")
177           && !strstr (XSTR (exp, 0), "const_double"))
178         NO_MODE_TEST (exp) = 1;
179       break;
180
181     case MATCH_TEST:
182     case NOT:
183       NO_MODE_TEST (exp) = 1;
184       break;
185
186     case AND:
187       mark_mode_tests (XEXP (exp, 0));
188       mark_mode_tests (XEXP (exp, 1));
189
190       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
191                             && NO_MODE_TEST (XEXP (exp, 1)));
192       break;
193       
194     case IOR:
195       mark_mode_tests (XEXP (exp, 0));
196       mark_mode_tests (XEXP (exp, 1));
197
198       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
199                             || NO_MODE_TEST (XEXP (exp, 1)));
200       break;
201
202     case IF_THEN_ELSE:
203       /* A ? B : C does a mode test if (one of A and B) does a mode
204          test, and C does too.  */
205       mark_mode_tests (XEXP (exp, 0));
206       mark_mode_tests (XEXP (exp, 1));
207       mark_mode_tests (XEXP (exp, 2));
208
209       NO_MODE_TEST (exp) = ((NO_MODE_TEST (XEXP (exp, 0))
210                              && NO_MODE_TEST (XEXP (exp, 1)))
211                             || NO_MODE_TEST (XEXP (exp, 2)));
212       break;
213
214     default:
215       error ("'%s' cannot be used in a define_predicate expression",
216              GET_RTX_NAME (GET_CODE (exp)));
217     }
218 }
219
220 /* Given a predicate, work out where in its RTL expression to add
221    tests for proper modes.  Special predicates do not get any such
222    tests.  We try to avoid adding tests when we don't have to; in
223    particular, other normal predicates can be counted on to do it for
224    us.  */
225
226 static void
227 add_mode_tests (struct pred_data *p)
228 {
229   rtx match_test_exp, and_exp;
230   rtx *pos;
231
232   /* Don't touch special predicates.  */
233   if (p->special)
234     return;
235
236   mark_mode_tests (p->exp);
237
238   /* If the whole expression already tests the mode, we're done.  */
239   if (!NO_MODE_TEST (p->exp))
240     return;
241
242   match_test_exp = rtx_alloc (MATCH_TEST);
243   XSTR (match_test_exp, 0) = "mode == VOIDmode || GET_MODE (op) == mode";
244   and_exp = rtx_alloc (AND);
245   XEXP (and_exp, 1) = match_test_exp;
246
247   /* It is always correct to rewrite p->exp as
248
249         (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
250
251      but there are a couple forms where we can do better.  If the
252      top-level pattern is an IOR, and one of the two branches does test
253      the mode, we can wrap just the branch that doesn't.  Likewise, if
254      we have an IF_THEN_ELSE, and one side of it tests the mode, we can
255      wrap just the side that doesn't.  And, of course, we can repeat this
256      descent as many times as it works.  */
257
258   pos = &p->exp;
259   for (;;)
260     {
261       rtx subexp = *pos;
262
263       switch (GET_CODE (subexp))
264         {
265         case IOR:
266           {
267             int test0 = NO_MODE_TEST (XEXP (subexp, 0));
268             int test1 = NO_MODE_TEST (XEXP (subexp, 1));
269             
270             gcc_assert (test0 || test1);
271             
272             if (test0 && test1)
273               goto break_loop;
274             pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
275           }
276           break;
277           
278         case IF_THEN_ELSE:
279           {
280             int test0 = NO_MODE_TEST (XEXP (subexp, 0));
281             int test1 = NO_MODE_TEST (XEXP (subexp, 1));
282             int test2 = NO_MODE_TEST (XEXP (subexp, 2));
283             
284             gcc_assert ((test0 && test1) || test2);
285             
286             if (test0 && test1 && test2)
287               goto break_loop;
288             if (test0 && test1)
289               /* Must put it on the dependent clause, not the
290                  controlling expression, or we change the meaning of
291                  the test.  */
292               pos = &XEXP (subexp, 1);
293             else
294               pos = &XEXP (subexp, 2);
295           }
296           break;
297           
298         default:
299           goto break_loop;
300         }
301     }
302  break_loop:
303   XEXP (and_exp, 0) = *pos;
304   *pos = and_exp;
305 }
306
307
308 /* CODES is a list of RTX codes.  Write out an expression which
309    determines whether the operand has one of those codes.  */
310 static void
311 write_match_code (const char *codes)
312 {
313   const char *code;
314
315   while ((code = scan_comma_elt (&codes)) != 0)
316     {
317       fputs ("GET_CODE (op) == ", stdout);
318       while (code < codes)
319         {
320           putchar (TOUPPER (*code));
321           code++;
322         }
323       
324       if (*codes == ',')
325         fputs (" || ", stdout);
326     }
327 }
328
329 /* EXP is an RTL (sub)expression for a predicate.  Recursively
330    descend the expression and write out an equivalent C expression.  */
331 static void
332 write_predicate_expr (const char *name, rtx exp)
333 {
334   switch (GET_CODE (exp))
335     {
336     case AND:
337       putchar ('(');
338       write_predicate_expr (name, XEXP (exp, 0));
339       fputs (") && (", stdout);
340       write_predicate_expr (name, XEXP (exp, 1));
341       putchar (')');
342       break;
343   
344     case IOR:
345       putchar ('(');
346       write_predicate_expr (name, XEXP (exp, 0));
347       fputs (") || (", stdout);
348       write_predicate_expr (name, XEXP (exp, 1));
349       putchar (')');
350       break;
351
352     case NOT:
353       fputs ("!(", stdout);
354       write_predicate_expr (name, XEXP (exp, 0));
355       putchar (')');
356       break;
357
358     case IF_THEN_ELSE:
359       putchar ('(');
360       write_predicate_expr (name, XEXP (exp, 0));
361       fputs (") ? (", stdout);
362       write_predicate_expr (name, XEXP (exp, 1));
363       fputs (") : (", stdout);
364       write_predicate_expr (name, XEXP (exp, 2));
365       putchar (')');
366       break;
367
368     case MATCH_OPERAND:
369       if (GET_MODE (exp) == VOIDmode)
370         printf ("%s (op, mode)", XSTR (exp, 1));
371       else
372         printf ("%s (op, %smode)", XSTR (exp, 1), mode_name[GET_MODE (exp)]);
373       break;
374
375     case MATCH_CODE:
376       write_match_code (XSTR (exp, 0));
377       break;
378
379     case MATCH_TEST:
380       fputs (XSTR (exp, 0), stdout);
381       break;
382
383     default:
384       error ("%s: cannot use '%s' in a predicate expression",
385              name, GET_RTX_NAME (GET_CODE (exp)));
386       putchar ('0');
387     }
388 }
389
390 /* Given a predicate, write out a complete C function to compute it.  */
391 static void
392 write_one_predicate_function (struct pred_data *p)
393 {
394   if (!p->exp)
395     return;
396
397   write_predicate_subfunction (p);
398   add_mode_tests (p);
399
400   /* A normal predicate can legitimately not look at enum machine_mode
401      if it accepts only CONST_INTs and/or CONST_DOUBLEs.  */
402   printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n"
403           "{\n  return ",
404           p->name);
405   write_predicate_expr (p->name, p->exp);
406   fputs (";\n}\n\n", stdout);
407 }
408
409 /* Write insn-preds.c.  
410    N.B. the list of headers to include was copied from genrecog; it
411    may not be ideal.
412
413    FUTURE: Write #line markers referring back to the machine
414    description.  (Can't practically do this now since we don't know
415    the line number of the C block - just the line number of the enclosing
416    expression.)  */
417 static void
418 write_insn_preds_c (void)
419 {
420   struct pred_data *p;
421
422   printf ("\
423 /* Generated automatically by the program '%s'\n\
424    from the machine description file '%s'.  */\n\n", progname, in_fname);
425
426   puts ("\
427 #include \"config.h\"\n\
428 #include \"system.h\"\n\
429 #include \"coretypes.h\"\n\
430 #include \"tm.h\"\n\
431 #include \"rtl.h\"\n\
432 #include \"tree.h\"\n\
433 #include \"tm_p.h\"\n\
434 #include \"function.h\"\n\
435 #include \"insn-config.h\"\n\
436 #include \"recog.h\"\n\
437 #include \"real.h\"\n\
438 #include \"output.h\"\n\
439 #include \"flags.h\"\n\
440 #include \"hard-reg-set.h\"\n\
441 #include \"resource.h\"\n\
442 #include \"toplev.h\"\n\
443 #include \"reload.h\"\n\
444 #include \"regs.h\"\n");
445
446   FOR_ALL_PREDICATES (p)
447     write_one_predicate_function (p);
448 }
449
450 /* Argument parsing.  */
451 static bool gen_header;
452 static bool
453 parse_option (const char *opt)
454 {
455   if (!strcmp (opt, "-h"))
456     {
457       gen_header = true;
458       return 1;
459     }
460   else
461     return 0;
462 }
463
464 /* Master control.  */
465 int
466 main (int argc, char **argv)
467 {
468   rtx defn;
469   int pattern_lineno, next_insn_code = 0;
470
471   progname = argv[0];
472   if (argc <= 1)
473     fatal ("no input file name");
474   if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
475     return FATAL_EXIT_CODE;
476
477   while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
478     {
479       if (GET_CODE (defn) == DEFINE_PREDICATE
480           || GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
481         process_define_predicate (defn);
482     }
483
484   if (gen_header)
485     write_tm_preds_h ();
486   else
487     write_insn_preds_c ();
488
489   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
490     return FATAL_EXIT_CODE;
491
492   return SUCCESS_EXIT_CODE;
493 }
494
495 /* Dummy for debugging purposes.  */
496 const char *
497 get_insn_name (int code ATTRIBUTE_UNUSED)
498 {
499   return 0;
500 }