Create startup files from the GCC sources and drop our versions.
[dragonfly.git] / contrib / gcc-4.0 / gcc / genconditions.c
1 /* Process machine description and calculate constant conditions.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
4    This file is part of GCC.
5
6    GCC is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GCC is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING.  If not, write to
18    the Free Software Foundation, 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 /* In a machine description, all of the insn patterns - define_insn,
22    define_expand, define_split, define_peephole, define_peephole2 -
23    contain an optional C expression which makes the final decision
24    about whether or not this pattern is usable.  That expression may
25    turn out to be always false when the compiler is built.  If it is,
26    most of the programs that generate code from the machine
27    description can simply ignore the entire pattern.  */
28
29 #include "bconfig.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "errors.h"
35 #include "hashtab.h"
36 #include "gensupport.h"
37
38 /* so we can include except.h in the generated file.  */
39 static int saw_eh_return;
40
41 static htab_t condition_table;
42
43 static void add_condition       (const char *);
44 static void write_header        (void);
45 static void write_conditions    (void);
46 static int write_one_condition  (void **, void *);
47
48 /* Record the C test expression EXPR in the condition_table.
49    Duplicates clobber previous entries, which leaks memory, but
50    we don't care for this application.  */
51
52 static void
53 add_condition (const char *expr)
54 {
55   struct c_test *test;
56
57   if (expr[0] == 0)
58     return;
59
60   test = XNEW (struct c_test);
61   test->expr = expr;
62
63   *(htab_find_slot (condition_table, test, INSERT)) = test;
64 }
65
66 /* Generate the header for insn-conditions.c.  */
67
68 static void
69 write_header (void)
70 {
71   puts ("\
72 /* Generated automatically by the program `genconditions' from the target\n\
73    machine description file.  */\n\
74 \n\
75 #include \"bconfig.h\"\n\
76 #include \"insn-constants.h\"\n");
77
78   puts ("\
79 /* Do not allow checking to confuse the issue.  */\n\
80 #undef ENABLE_CHECKING\n\
81 #undef ENABLE_TREE_CHECKING\n\
82 #undef ENABLE_RTL_CHECKING\n\
83 #undef ENABLE_RTL_FLAG_CHECKING\n\
84 #undef ENABLE_GC_CHECKING\n\
85 #undef ENABLE_GC_ALWAYS_COLLECT\n");
86
87   puts ("\
88 #include \"system.h\"\n\
89 #if GCC_VERSION < 3001\n\
90 #include \"dummy-conditions.c\"\n\
91 #else\n\
92 #include \"coretypes.h\"\n\
93 #include \"tm.h\"\n\
94 #include \"rtl.h\"\n\
95 #include \"tm_p.h\"\n\
96 #include \"function.h\"\n");
97
98   puts ("\
99 /* Fake - insn-config.h doesn't exist yet.  */\n\
100 #define MAX_RECOG_OPERANDS 10\n\
101 #define MAX_DUP_OPERANDS 10\n\
102 #define MAX_INSNS_PER_SPLIT 5\n");
103
104   puts ("\
105 #include \"regs.h\"\n\
106 #include \"recog.h\"\n\
107 #include \"real.h\"\n\
108 #include \"output.h\"\n\
109 #include \"flags.h\"\n\
110 #include \"hard-reg-set.h\"\n\
111 #include \"resource.h\"\n\
112 #include \"toplev.h\"\n\
113 #include \"reload.h\"\n\
114 #include \"gensupport.h\"\n");
115
116   if (saw_eh_return)
117     puts ("#define HAVE_eh_return 1");
118   puts ("#include \"except.h\"\n");
119
120   puts ("\
121 /* Dummy external declarations.  */\n\
122 extern rtx insn;\n\
123 extern rtx ins1;\n\
124 extern rtx operands[];\n");
125
126   puts ("\
127 /* If we don't have __builtin_constant_p, or it's not acceptable in\n\
128    array initializers, fall back (by using dummy-conditions.c above)\n\
129    to assuming that all conditions potentially vary at run time.  It\n\
130    works in 3.0.1 and later; 3.0 only when not optimizing.  */\n\
131 #define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)\n");
132 }
133
134 /* Write out one entry in the conditions table, using the data pointed
135    to by SLOT.  Each entry looks like this:
136   { "! optimize_size && ! TARGET_READ_MODIFY_WRITE",
137     MAYBE_EVAL (! optimize_size && ! TARGET_READ_MODIFY_WRITE) },  */
138
139 static int
140 write_one_condition (void **slot, void * ARG_UNUSED (dummy))
141 {
142   const struct c_test *test = * (const struct c_test **) slot;
143   const char *p;
144
145   fputs ("  { \"", stdout);
146   for (p = test->expr; *p; p++)
147     {
148       if (*p == '\n')
149         fputs ("\\n\\\n", stdout);
150       else if (*p == '"')
151         fputs ("\\\"", stdout);
152       else
153         putchar (*p);
154     }
155
156   printf ("\",\n    MAYBE_EVAL (%s) },\n", test->expr);
157   return 1;
158 }
159
160 /* Write out the complete conditions table, its size, and a flag
161    indicating that gensupport.c can now do insn elision.  */
162 static void
163 write_conditions (void)
164 {
165   puts ("\
166 /* This table lists each condition found in the machine description.\n\
167    Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
168    cannot be calculated at compile time. */\n\
169 \n\
170 const struct c_test insn_conditions[] = {");
171
172   htab_traverse (condition_table, write_one_condition, 0);
173
174   puts ("};\n");
175
176   printf ("const size_t n_insn_conditions = %lu;\n",
177           (unsigned long) htab_elements (condition_table));
178   puts ("const int insn_elision_unavailable = 0;\n#endif");
179 }
180
181 int
182 main (int argc, char **argv)
183 {
184   rtx desc;
185   int pattern_lineno; /* not used */
186   int code;
187
188   progname = "genconditions";
189
190   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
191     return (FATAL_EXIT_CODE);
192
193   condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL);
194
195   /* Read the machine description.  */
196
197   while (1)
198     {
199       desc = read_md_rtx (&pattern_lineno, &code);
200       if (desc == NULL)
201         break;
202
203       /* N.B. define_insn_and_split, define_cond_exec are handled
204          entirely within read_md_rtx; we never see them.  */
205       switch (GET_CODE (desc))
206         {
207         default:
208           break;
209
210         case DEFINE_INSN:
211         case DEFINE_EXPAND:
212           add_condition (XSTR (desc, 2));
213           /* except.h needs to know whether there is an eh_return
214              pattern in the machine description.  */
215           if (!strcmp (XSTR (desc, 0), "eh_return"))
216             saw_eh_return = 1;
217           break;
218
219         case DEFINE_SPLIT:
220         case DEFINE_PEEPHOLE:
221         case DEFINE_PEEPHOLE2:
222           add_condition (XSTR (desc, 1));
223           break;
224         }
225     }
226
227   write_header ();
228   write_conditions ();
229
230   fflush (stdout);
231   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
232 }