OSDN Git Service

* de.po: Update.
[pf3gnuchains/gcc-fork.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 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)
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       printf ("%s (op, mode)", XSTR (exp, 1));
370       break;
371
372     case MATCH_CODE:
373       write_match_code (XSTR (exp, 0));
374       break;
375
376     case MATCH_TEST:
377       fputs (XSTR (exp, 0), stdout);
378       break;
379
380     default:
381       error ("%s: cannot use '%s' in a predicate expression",
382              name, GET_RTX_NAME (GET_CODE (exp)));
383       putchar ('0');
384     }
385 }
386
387 /* Given a predicate, write out a complete C function to compute it.  */
388 static void
389 write_one_predicate_function (struct pred_data *p)
390 {
391   if (!p->exp)
392     return;
393
394   write_predicate_subfunction (p);
395   add_mode_tests (p);
396
397   /* A normal predicate can legitimately not look at enum machine_mode
398      if it accepts only CONST_INTs and/or CONST_DOUBLEs.  */
399   printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n"
400           "{\n  return ",
401           p->name);
402   write_predicate_expr (p->name, p->exp);
403   fputs (";\n}\n\n", stdout);
404 }
405
406 /* Write insn-preds.c.  
407    N.B. the list of headers to include was copied from genrecog; it
408    may not be ideal.
409
410    FUTURE: Write #line markers referring back to the machine
411    description.  (Can't practically do this now since we don't know
412    the line number of the C block - just the line number of the enclosing
413    expression.)  */
414 static void
415 write_insn_preds_c (void)
416 {
417   struct pred_data *p;
418
419   printf ("\
420 /* Generated automatically by the program '%s'\n\
421    from the machine description file '%s'.  */\n\n", progname, in_fname);
422
423   puts ("\
424 #include \"config.h\"\n\
425 #include \"system.h\"\n\
426 #include \"coretypes.h\"\n\
427 #include \"tm.h\"\n\
428 #include \"rtl.h\"\n\
429 #include \"tree.h\"\n\
430 #include \"tm_p.h\"\n\
431 #include \"function.h\"\n\
432 #include \"insn-config.h\"\n\
433 #include \"recog.h\"\n\
434 #include \"real.h\"\n\
435 #include \"output.h\"\n\
436 #include \"flags.h\"\n\
437 #include \"hard-reg-set.h\"\n\
438 #include \"resource.h\"\n\
439 #include \"toplev.h\"\n\
440 #include \"reload.h\"\n");
441
442   FOR_ALL_PREDICATES (p)
443     write_one_predicate_function (p);
444 }
445
446 /* Argument parsing.  */
447 static bool gen_header;
448 static bool
449 parse_option (const char *opt)
450 {
451   if (!strcmp (opt, "-h"))
452     {
453       gen_header = true;
454       return 1;
455     }
456   else
457     return 0;
458 }
459
460 /* Master control.  */
461 int
462 main (int argc, char **argv)
463 {
464   rtx defn;
465   int pattern_lineno, next_insn_code = 0;
466
467   progname = argv[0];
468   if (argc <= 1)
469     fatal ("no input file name");
470   if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
471     return FATAL_EXIT_CODE;
472
473   while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
474     {
475       if (GET_CODE (defn) == DEFINE_PREDICATE
476           || GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
477         process_define_predicate (defn);
478     }
479
480   if (gen_header)
481     write_tm_preds_h ();
482   else
483     write_insn_preds_c ();
484
485   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
486     return FATAL_EXIT_CODE;
487
488   return SUCCESS_EXIT_CODE;
489 }
490
491 /* Dummy for debugging purposes.  */
492 const char *
493 get_insn_name (int code ATTRIBUTE_UNUSED)
494 {
495   return 0;
496 }