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