OSDN Git Service

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