]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gengenrtl.c
Makefile.in (HOST_RTL): Add $(HOST_PREFIX)bitmap.o.
[thirdparty/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((char));
48 static const char *accessor_from_format PROTO((char));
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 char 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 char 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 }
134
135 static void
136 find_formats ()
137 {
138 int i;
139
140 for (i = 0; i < NUM_RTX_CODE; ++i)
141 {
142 const char **f;
143
144 if (special_format (defs[i].format))
145 continue;
146
147 for (f = formats; *f ; ++f)
148 if (!strcmp(*f, defs[i].format))
149 break;
150
151 if (!*f)
152 *f = defs[i].format;
153 }
154 }
155
156 static void
157 gendecl (f, format)
158 FILE *f;
159 const char *format;
160 {
161 const char *p;
162 int i;
163
164 fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
165 format);
166 for (p = format, i = 0; *p ; ++p)
167 if (*p != '0')
168 fprintf (f, ", %s arg%d", type_from_format (*p), i++);
169 fprintf (f, "));\n");
170 }
171
172 static void
173 genmacro (f, idx)
174 FILE *f;
175 int idx;
176 {
177 const char *p;
178 int i;
179
180 fprintf (f, "#define gen_rtx_%s%s(mode",
181 (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
182
183 for (p = defs[idx].format, i = 0; *p ; ++p)
184 if (*p != '0')
185 fprintf (f, ", arg%d", i++);
186 fprintf (f, ") ");
187
188 fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
189 for (p = defs[idx].format, i = 0; *p ; ++p)
190 if (*p != '0')
191 fprintf (f, ",(arg%d)", i++);
192 fprintf (f, ")\n");
193 }
194
195 static void
196 gendef (f, format)
197 FILE *f;
198 const char *format;
199 {
200 const char *p;
201 int i, j;
202
203 fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
204 for (p = format, i = 0; *p ; ++p)
205 if (*p != '0')
206 fprintf (f, ", arg%d", i++);
207
208 fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
209 for (p = format, i = 0; *p ; ++p)
210 if (*p != '0')
211 fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
212
213 /* See rtx_alloc in rtl.c for comments. */
214 fprintf (f, "{\n");
215 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
216 (int) strlen (format) - 1);
217
218 fprintf (f, " PUT_CODE (rt, code);\n");
219 fprintf (f, " PUT_MODE (rt, mode);\n");
220
221 for (p = format, i = j = 0; *p ; ++p, ++i)
222 if (*p != '0')
223 {
224 fprintf (f, " %s (rt, %d) = arg%d;\n",
225 accessor_from_format (*p), i, j++);
226 }
227
228 fprintf (f, "\n return rt;\n}\n\n");
229 }
230
231 static void
232 genlegend (f)
233 FILE *f;
234 {
235 fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
236 fprintf (f, " from the RTL description file `rtl.def' */\n\n");
237 }
238
239 static void
240 genheader (f)
241 FILE *f;
242 {
243 int i;
244 const char **fmt;
245
246 for (fmt = formats; *fmt; ++fmt)
247 gendecl (f, *fmt);
248
249 fprintf(f, "\n");
250
251 for (i = 0; i < NUM_RTX_CODE; i++)
252 {
253 if (special_format (defs[i].format))
254 continue;
255 genmacro (f, i);
256 }
257 }
258
259 static void
260 gencode (f)
261 FILE *f;
262 {
263 const char **fmt;
264
265 fputs ("#include \"config.h\"\n", f);
266 fputs ("#include \"system.h\"\n", f);
267 fputs ("#include \"obstack.h\"\n", f);
268 fputs ("#include \"rtl.h\"\n\n", f);
269 fputs ("extern struct obstack *rtl_obstack;\n\n", f);
270 fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
271 fputs ("static rtx obstack_alloc_rtx (length)\n", f);
272 fputs (" register int length;\n{\n", f);
273 fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
274 fputs (" if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n", f);
275 fputs (" *(int *)rt = 0;\n", f);
276 fputs (" else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n", f);
277 fputs (" *(HOST_WIDE_INT *)rt = 0;\n", f);
278 fputs (" else\n", f);
279 fputs (" bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
280 fputs (" return rt;\n}\n\n", f);
281
282 for (fmt = formats; *fmt; ++fmt)
283 gendef (f, *fmt);
284 }
285
286 #if defined(USE_C_ALLOCA) && !defined(__GNUC__)
287 char *
288 xmalloc (nbytes)
289 int nbytes;
290 {
291 char *tmp = (char *) malloc (nbytes);
292
293 if (!tmp)
294 {
295 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
296 exit (FATAL_EXIT_CODE);
297 }
298
299 return tmp;
300 }
301 #endif /* USE_C_ALLOCA && !__GNUC__ */
302
303 int
304 main(argc, argv)
305 int argc;
306 char **argv;
307 {
308 FILE *f;
309
310 if (argc != 3)
311 exit (1);
312
313 find_formats ();
314
315 f = fopen (argv[1], "w");
316 if (f == NULL)
317 {
318 perror(argv[1]);
319 exit (1);
320 }
321 genlegend (f);
322 genheader (f);
323 fclose(f);
324
325 f = fopen (argv[2], "w");
326 if (f == NULL)
327 {
328 perror(argv[2]);
329 exit (1);
330 }
331 genlegend (f);
332 gencode (f);
333 fclose(f);
334
335 exit (0);
336 }