* arm.c (arm_split_constant): Don't try to force a constant to
[official-gcc.git] / gcc / gengenrtl.c
blob8f811fc010eabf97251fb2d0037eba7d7f2a3452
1 /* Generate code to allocate RTL structures.
2 Copyright (C) 1997, 1998 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"
25 #define NO_GENRTL_H
26 #include "rtl.h"
29 struct rtx_definition
31 const char *enumname, *name, *format;
34 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
36 struct rtx_definition defs[] =
38 #include "rtl.def" /* rtl expressions are documented here */
41 const char *formats[NUM_RTX_CODE];
43 static const char *type_from_format PROTO((int));
44 static const char *accessor_from_format PROTO((int));
45 static int special_format PROTO((const char *));
46 static int special_rtx PROTO((int));
47 static void find_formats PROTO((void));
48 static void gendecl PROTO((FILE *, const char *));
49 static void genmacro PROTO((FILE *, int));
50 static void gendef PROTO((FILE *, const char *));
51 static void genlegend PROTO((FILE *));
52 static void genheader PROTO((FILE *));
53 static void gencode PROTO((FILE *));
55 static const char *
56 type_from_format (c)
57 int c;
59 switch (c)
61 case 'i':
62 return "int";
63 case 'w':
64 return "HOST_WIDE_INT";
65 case 's':
66 return "char *";
67 case 'e':
68 case 'u':
69 return "rtx";
70 case 'E':
71 return "rtvec";
72 /* ?!? These should be bitmap and tree respectively, but those types
73 are not available in many of the files which include the output
74 of gengenrtl.
76 These are only used in prototypes, so I think we can assume that
77 void * is useable. */
78 case 'b':
79 return "void *";
80 case 't':
81 return "void *";
82 default:
83 abort ();
87 static const char *
88 accessor_from_format (c)
89 int c;
91 switch (c)
93 case 'i':
94 return "XINT";
95 case 'w':
96 return "XWINT";
97 case 's':
98 return "XSTR";
99 case 'e':
100 case 'u':
101 return "XEXP";
102 case 'E':
103 return "XVEC";
104 case 'b':
105 return "XBITMAP";
106 case 't':
107 return "XTREE";
108 default:
109 abort ();
113 static int
114 special_format (fmt)
115 const char *fmt;
117 return (strchr (fmt, '*') != 0
118 || strchr (fmt, 'V') != 0
119 || strchr (fmt, 'S') != 0
120 || strchr (fmt, 'n') != 0);
123 static int
124 special_rtx (idx)
125 int idx;
127 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
128 || strcmp (defs[idx].enumname, "REG") == 0
129 || strcmp (defs[idx].enumname, "MEM") == 0);
132 static void
133 find_formats ()
135 int i;
137 for (i = 0; i < NUM_RTX_CODE; ++i)
139 const char **f;
141 if (special_format (defs[i].format))
142 continue;
144 for (f = formats; *f ; ++f)
145 if (!strcmp(*f, defs[i].format))
146 break;
148 if (!*f)
149 *f = defs[i].format;
153 static void
154 gendecl (f, format)
155 FILE *f;
156 const char *format;
158 const char *p;
159 int i;
161 fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
162 format);
163 for (p = format, i = 0; *p ; ++p)
164 if (*p != '0')
165 fprintf (f, ", %s arg%d", type_from_format (*p), i++);
166 fprintf (f, "));\n");
169 static void
170 genmacro (f, idx)
171 FILE *f;
172 int idx;
174 const char *p;
175 int i;
177 fprintf (f, "#define gen_rtx_%s%s(mode",
178 (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
180 for (p = defs[idx].format, i = 0; *p ; ++p)
181 if (*p != '0')
182 fprintf (f, ", arg%d", i++);
183 fprintf (f, ") ");
185 fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
186 for (p = defs[idx].format, i = 0; *p ; ++p)
187 if (*p != '0')
188 fprintf (f, ",(arg%d)", i++);
189 fprintf (f, ")\n");
192 static void
193 gendef (f, format)
194 FILE *f;
195 const char *format;
197 const char *p;
198 int i, j;
200 fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
201 for (p = format, i = 0; *p ; ++p)
202 if (*p != '0')
203 fprintf (f, ", arg%d", i++);
205 fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
206 for (p = format, i = 0; *p ; ++p)
207 if (*p != '0')
208 fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
210 /* See rtx_alloc in rtl.c for comments. */
211 fprintf (f, "{\n");
212 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
213 (int) strlen (format) - 1);
215 fprintf (f, " PUT_CODE (rt, code);\n");
216 fprintf (f, " PUT_MODE (rt, mode);\n");
218 for (p = format, i = j = 0; *p ; ++p, ++i)
219 if (*p != '0')
221 fprintf (f, " %s (rt, %d) = arg%d;\n",
222 accessor_from_format (*p), i, j++);
225 fprintf (f, "\n return rt;\n}\n\n");
228 static void
229 genlegend (f)
230 FILE *f;
232 fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
233 fprintf (f, " from the RTL description file `rtl.def' */\n\n");
236 static void
237 genheader (f)
238 FILE *f;
240 int i;
241 const char **fmt;
243 for (fmt = formats; *fmt; ++fmt)
244 gendecl (f, *fmt);
246 fprintf(f, "\n");
248 for (i = 0; i < NUM_RTX_CODE; i++)
250 if (special_format (defs[i].format))
251 continue;
252 genmacro (f, i);
256 static void
257 gencode (f)
258 FILE *f;
260 const char **fmt;
262 fputs ("#include \"config.h\"\n", f);
263 fputs ("#include \"system.h\"\n", f);
264 fputs ("#include \"obstack.h\"\n", f);
265 fputs ("#include \"rtl.h\"\n\n", f);
266 fputs ("extern struct obstack *rtl_obstack;\n\n", f);
267 fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
268 fputs ("static rtx obstack_alloc_rtx (length)\n", f);
269 fputs (" register int length;\n{\n", f);
270 fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
271 fputs (" bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
272 fputs (" return rt;\n}\n\n", f);
274 for (fmt = formats; *fmt; ++fmt)
275 gendef (f, *fmt);
278 #if defined(USE_C_ALLOCA)
280 xmalloc (nbytes)
281 size_t nbytes;
283 register PTR tmp = (PTR) malloc (nbytes);
285 if (!tmp)
287 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
288 nbytes);
289 exit (FATAL_EXIT_CODE);
292 return tmp;
294 #endif /* USE_C_ALLOCA */
297 main(argc, argv)
298 int argc;
299 char **argv;
301 FILE *f;
303 if (argc != 3)
304 exit (1);
306 find_formats ();
308 f = fopen (argv[1], "w");
309 if (f == NULL)
311 perror(argv[1]);
312 exit (1);
314 genlegend (f);
315 genheader (f);
316 fclose(f);
318 f = fopen (argv[2], "w");
319 if (f == NULL)
321 perror(argv[2]);
322 exit (1);
324 genlegend (f);
325 gencode (f);
326 fclose(f);
328 exit (0);