* recog.c (preproces_constraints): Zero recog_op_alt before
[official-gcc.git] / gcc / gengenrtl.c
blobbf98a716770d3293b5ab5fd6d4b7d1298dfce012
1 /* Generate code to allocate RTL structures.
2 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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.
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.
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. */
22 #include "hconfig.h"
23 #include "system.h"
24 #undef abort
26 #define NO_GENRTL_H
27 #include "rtl.h"
30 struct rtx_definition
32 const char *enumname, *name, *format;
35 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
37 struct rtx_definition defs[] =
39 #include "rtl.def" /* rtl expressions are documented here */
42 const char *formats[NUM_RTX_CODE];
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 *));
56 /* Decode a format letter into a C type string. */
58 static const char *
59 type_from_format (c)
60 int c;
62 switch (c)
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 /* ?!? These should be bitmap and tree respectively, but those types
76 are not available in many of the files which include the output
77 of gengenrtl.
79 These are only used in prototypes, so I think we can assume that
80 void * is useable. */
81 case 'b':
82 return "void *";
83 case 't':
84 return "void *";
85 default:
86 abort ();
90 /* Decode a format letter into the proper accessor function. */
92 static const char *
93 accessor_from_format (c)
94 int c;
96 switch (c)
98 case 'i':
99 return "XINT";
100 case 'w':
101 return "XWINT";
102 case 's':
103 return "XSTR";
104 case 'e':
105 case 'u':
106 return "XEXP";
107 case 'E':
108 return "XVEC";
109 case 'b':
110 return "XBITMAP";
111 case 't':
112 return "XTREE";
113 default:
114 abort ();
118 /* Return true if a format character doesn't need normal processing. */
120 static int
121 special_format (fmt)
122 const char *fmt;
124 return (strchr (fmt, '*') != 0
125 || strchr (fmt, 'V') != 0
126 || strchr (fmt, 'S') != 0
127 || strchr (fmt, 'n') != 0);
130 /* Return true if an rtx requires special processing. */
132 static int
133 special_rtx (idx)
134 int idx;
136 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
137 || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
138 || strcmp (defs[idx].enumname, "REG") == 0
139 || strcmp (defs[idx].enumname, "MEM") == 0);
142 /* Fill `formats' with all unique format strings. */
144 static void
145 find_formats ()
147 int i;
149 for (i = 0; i < NUM_RTX_CODE; ++i)
151 const char **f;
153 if (special_format (defs[i].format))
154 continue;
156 for (f = formats; *f ; ++f)
157 if (! strcmp (*f, defs[i].format))
158 break;
160 if (!*f)
161 *f = defs[i].format;
165 /* Emit a prototype for the rtx generator for a format. */
167 static void
168 gendecl (f, format)
169 FILE *f;
170 const char *format;
172 const char *p;
173 int i;
175 fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
176 format);
177 for (p = format, i = 0; *p ; ++p)
178 if (*p != '0')
179 fprintf (f, ", %s arg%d", type_from_format (*p), i++);
180 fprintf (f, "));\n");
183 /* Emit a define mapping an rtx code to the generator for its format. */
185 static void
186 genmacro (f, idx)
187 FILE *f;
188 int idx;
190 const char *p;
191 int i;
193 fprintf (f, "#define gen_rtx_%s%s(mode",
194 (special_rtx (idx) ? "raw_" : ""), 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, ") ");
201 fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
202 for (p = defs[idx].format, i = 0; *p ; ++p)
203 if (*p != '0')
204 fprintf (f, ",(arg%d)", i++);
205 fprintf (f, ")\n");
208 /* Emit the implementation for the rtx generator for a format. */
210 static void
211 gendef (f, format)
212 FILE *f;
213 const char *format;
215 const char *p;
216 int i, j;
218 fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
219 for (p = format, i = 0; *p ; ++p)
220 if (*p != '0')
221 fprintf (f, ", arg%d", i++);
223 fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
224 for (p = format, i = 0; *p ; ++p)
225 if (*p != '0')
226 fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
228 /* See rtx_alloc in rtl.c for comments. */
229 fprintf (f, "{\n");
230 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
231 (int) strlen (format) - 1);
233 fprintf (f, " PUT_CODE (rt, code);\n");
234 fprintf (f, " PUT_MODE (rt, mode);\n");
236 for (p = format, i = j = 0; *p ; ++p, ++i)
237 if (*p != '0')
239 fprintf (f, " %s (rt, %d) = arg%d;\n",
240 accessor_from_format (*p), i, j++);
243 fprintf (f, "\n return rt;\n}\n\n");
246 /* Emit the `do not edit' banner. */
248 static void
249 genlegend (f)
250 FILE *f;
252 fputs ("/* Generated automaticaly by the program `gengenrtl'\n", f);
253 fputs (" from the RTL description file `rtl.def' */\n\n", f);
256 /* Emit "genrtl.h". */
258 static void
259 genheader (f)
260 FILE *f;
262 int i;
263 const char **fmt;
265 for (fmt = formats; *fmt; ++fmt)
266 gendecl (f, *fmt);
268 fprintf (f, "\n");
270 for (i = 0; i < NUM_RTX_CODE; i++)
272 if (special_format (defs[i].format))
273 continue;
274 genmacro (f, i);
278 /* Emit "genrtl.c". */
280 static void
281 gencode (f)
282 FILE *f;
284 const char **fmt;
286 fputs ("#include \"config.h\"\n", f);
287 fputs ("#include \"system.h\"\n", f);
288 fputs ("#include \"obstack.h\"\n", f);
289 fputs ("#include \"rtl.h\"\n\n", f);
290 fputs ("extern struct obstack *rtl_obstack;\n\n", f);
291 fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
292 fputs ("static rtx obstack_alloc_rtx (length)\n", f);
293 fputs (" register int length;\n{\n", f);
294 fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
295 fputs (" memset(rt, 0, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
296 fputs (" return rt;\n}\n\n", f);
298 for (fmt = formats; *fmt; ++fmt)
299 gendef (f, *fmt);
302 #if defined(USE_C_ALLOCA)
304 xmalloc (nbytes)
305 size_t nbytes;
307 register PTR tmp = (PTR) malloc (nbytes);
309 if (!tmp)
311 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
312 nbytes);
313 exit (FATAL_EXIT_CODE);
316 return tmp;
318 #endif /* USE_C_ALLOCA */
321 main(argc, argv)
322 int argc;
323 char **argv;
325 FILE *f;
327 if (argc != 3)
328 exit (1);
330 find_formats ();
332 f = fopen (argv[1], "w");
333 if (f == NULL)
335 perror (argv[1]);
336 exit (1);
338 genlegend (f);
339 genheader (f);
340 fclose (f);
342 f = fopen (argv[2], "w");
343 if (f == NULL)
345 perror (argv[2]);
346 exit (1);
348 genlegend (f);
349 gencode (f);
350 fclose (f);
352 exit (0);