invoke.texi (-fstrict-aliasing): Document.
[gcc.git] / gcc / gengenrtl.c
1 /* Generate code to allocate RTL structures.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC 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 GNU CC 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 GNU CC; 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
22 #include "hconfig.h"
23 #include "system.h"
24
25 #include "obstack.h"
26 #define obstack_chunk_alloc xmalloc
27 #define obstack_chunk_free free
28
29 #define NO_GENRTL_H
30 #include "rtl.h"
31
32
33 struct rtx_definition
34 {
35 const char *enumname, *name, *format;
36 };
37
38 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
39
40 struct rtx_definition defs[] =
41 {
42 #include "rtl.def" /* rtl expressions are documented here */
43 };
44
45 const char *formats[NUM_RTX_CODE];
46
47 static const char *type_from_format PROTO((int));
48 static const char *accessor_from_format PROTO((int));
49 static int special_format PROTO((const char *));
50 static int special_rtx PROTO((int));
51 static void find_formats PROTO((void));
52 static void gendecl PROTO((FILE *, const char *));
53 static void genmacro PROTO((FILE *, int));
54 static void gendef PROTO((FILE *, const char *));
55 static void genlegend PROTO((FILE *));
56 static void genheader PROTO((FILE *));
57 static void gencode PROTO((FILE *));
58
59 static const char *
60 type_from_format (c)
61 int c;
62 {
63 switch (c)
64 {
65 case 'i':
66 return "int";
67 case 'w':
68 return "HOST_WIDE_INT";
69 case 's':
70 return "char *";
71 case 'e':
72 case 'u':
73 return "rtx";
74 case 'E':
75 return "rtvec";
76 /* ?!? These should be bitmap and tree respectively, but those types
77 are not available in many of the files which include the output
78 of gengenrtl.
79
80 These are only used in prototypes, so I think we can assume that
81 void * is useable. */
82 case 'b':
83 return "void *";
84 case 't':
85 return "void *";
86 default:
87 abort ();
88 }
89 }
90
91 static const char *
92 accessor_from_format (c)
93 int c;
94 {
95 switch (c)
96 {
97 case 'i':
98 return "XINT";
99 case 'w':
100 return "XWINT";
101 case 's':
102 return "XSTR";
103 case 'e':
104 case 'u':
105 return "XEXP";
106 case 'E':
107 return "XVEC";
108 case 'b':
109 return "XBITMAP";
110 case 't':
111 return "XTREE";
112 default:
113 abort ();
114 }
115 }
116
117 static int
118 special_format (fmt)
119 const char *fmt;
120 {
121 return (strchr (fmt, '*') != 0
122 || strchr (fmt, 'V') != 0
123 || strchr (fmt, 'S') != 0
124 || strchr (fmt, 'n') != 0);
125 }
126
127 static int
128 special_rtx (idx)
129 int idx;
130 {
131 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
132 || strcmp (defs[idx].enumname, "REG") == 0
133 || strcmp (defs[idx].enumname, "MEM") == 0);
134 }
135
136 static void
137 find_formats ()
138 {
139 int i;
140
141 for (i = 0; i < NUM_RTX_CODE; ++i)
142 {
143 const char **f;
144
145 if (special_format (defs[i].format))
146 continue;
147
148 for (f = formats; *f ; ++f)
149 if (!strcmp(*f, defs[i].format))
150 break;
151
152 if (!*f)
153 *f = defs[i].format;
154 }
155 }
156
157 static void
158 gendecl (f, format)
159 FILE *f;
160 const char *format;
161 {
162 const char *p;
163 int i;
164
165 fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
166 format);
167 for (p = format, i = 0; *p ; ++p)
168 if (*p != '0')
169 fprintf (f, ", %s arg%d", type_from_format (*p), i++);
170 fprintf (f, "));\n");
171 }
172
173 static void
174 genmacro (f, idx)
175 FILE *f;
176 int idx;
177 {
178 const char *p;
179 int i;
180
181 fprintf (f, "#define gen_rtx_%s%s(mode",
182 (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
183
184 for (p = defs[idx].format, i = 0; *p ; ++p)
185 if (*p != '0')
186 fprintf (f, ", arg%d", i++);
187 fprintf (f, ") ");
188
189 fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
190 for (p = defs[idx].format, i = 0; *p ; ++p)
191 if (*p != '0')
192 fprintf (f, ",(arg%d)", i++);
193 fprintf (f, ")\n");
194 }
195
196 static void
197 gendef (f, format)
198 FILE *f;
199 const char *format;
200 {
201 const char *p;
202 int i, j;
203
204 fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
205 for (p = format, i = 0; *p ; ++p)
206 if (*p != '0')
207 fprintf (f, ", arg%d", i++);
208
209 fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
210 for (p = format, i = 0; *p ; ++p)
211 if (*p != '0')
212 fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
213
214 /* See rtx_alloc in rtl.c for comments. */
215 fprintf (f, "{\n");
216 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
217 (int) strlen (format) - 1);
218
219 fprintf (f, " PUT_CODE (rt, code);\n");
220 fprintf (f, " PUT_MODE (rt, mode);\n");
221
222 for (p = format, i = j = 0; *p ; ++p, ++i)
223 if (*p != '0')
224 {
225 fprintf (f, " %s (rt, %d) = arg%d;\n",
226 accessor_from_format (*p), i, j++);
227 }
228
229 fprintf (f, "\n return rt;\n}\n\n");
230 }
231
232 static void
233 genlegend (f)
234 FILE *f;
235 {
236 fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
237 fprintf (f, " from the RTL description file `rtl.def' */\n\n");
238 }
239
240 static void
241 genheader (f)
242 FILE *f;
243 {
244 int i;
245 const char **fmt;
246
247 for (fmt = formats; *fmt; ++fmt)
248 gendecl (f, *fmt);
249
250 fprintf(f, "\n");
251
252 for (i = 0; i < NUM_RTX_CODE; i++)
253 {
254 if (special_format (defs[i].format))
255 continue;
256 genmacro (f, i);
257 }
258 }
259
260 static void
261 gencode (f)
262 FILE *f;
263 {
264 const char **fmt;
265
266 fputs ("#include \"config.h\"\n", f);
267 fputs ("#include \"system.h\"\n", f);
268 fputs ("#include \"obstack.h\"\n", f);
269 fputs ("#include \"rtl.h\"\n\n", f);
270 fputs ("extern struct obstack *rtl_obstack;\n\n", f);
271 fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
272 fputs ("static rtx obstack_alloc_rtx (length)\n", f);
273 fputs (" register int length;\n{\n", f);
274 fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
275 fputs (" if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n", f);
276 fputs (" *(int *)rt = 0;\n", f);
277 fputs (" else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n", f);
278 fputs (" *(HOST_WIDE_INT *)rt = 0;\n", f);
279 fputs (" else\n", f);
280 fputs (" bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
281 fputs (" return rt;\n}\n\n", f);
282
283 for (fmt = formats; *fmt; ++fmt)
284 gendef (f, *fmt);
285 }
286
287 #if defined(USE_C_ALLOCA) && !defined(__GNUC__)
288 char *
289 xmalloc (nbytes)
290 int nbytes;
291 {
292 char *tmp = (char *) malloc (nbytes);
293
294 if (!tmp)
295 {
296 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
297 exit (FATAL_EXIT_CODE);
298 }
299
300 return tmp;
301 }
302 #endif /* USE_C_ALLOCA && !__GNUC__ */
303
304 int
305 main(argc, argv)
306 int argc;
307 char **argv;
308 {
309 FILE *f;
310
311 if (argc != 3)
312 exit (1);
313
314 find_formats ();
315
316 f = fopen (argv[1], "w");
317 if (f == NULL)
318 {
319 perror(argv[1]);
320 exit (1);
321 }
322 genlegend (f);
323 genheader (f);
324 fclose(f);
325
326 f = fopen (argv[2], "w");
327 if (f == NULL)
328 {
329 perror(argv[2]);
330 exit (1);
331 }
332 genlegend (f);
333 gencode (f);
334 fclose(f);
335
336 exit (0);
337 }