OSDN Git Service

8f811fc010eabf97251fb2d0037eba7d7f2a3452
[pf3gnuchains/gcc-fork.git] / gcc / gengenrtl.c
1 /* Generate code to allocate RTL structures.
2    Copyright (C) 1997, 1998 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 static const char *
56 type_from_format (c)
57      int c;
58 {
59   switch (c)
60     {
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.
75
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 ();
84     }
85 }
86
87 static const char *
88 accessor_from_format (c)
89      int c;
90 {
91   switch (c)
92     {
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 ();
110     }
111 }
112
113 static int
114 special_format (fmt)
115      const char *fmt;
116 {
117   return (strchr (fmt, '*') != 0
118           || strchr (fmt, 'V') != 0
119           || strchr (fmt, 'S') != 0
120           || strchr (fmt, 'n') != 0);
121 }
122
123 static int
124 special_rtx (idx)
125      int idx;
126 {
127   return (strcmp (defs[idx].enumname, "CONST_INT") == 0
128           || strcmp (defs[idx].enumname, "REG") == 0
129           || strcmp (defs[idx].enumname, "MEM") == 0);
130 }
131
132 static void
133 find_formats ()
134 {
135   int i;
136
137   for (i = 0; i < NUM_RTX_CODE; ++i)
138     {
139       const char **f;
140
141       if (special_format (defs[i].format))
142         continue;
143
144       for (f = formats; *f ; ++f)
145         if (!strcmp(*f, defs[i].format))
146           break;
147
148       if (!*f)
149         *f = defs[i].format;
150     }
151 }
152
153 static void
154 gendecl (f, format)
155      FILE *f;
156      const char *format;
157 {
158   const char *p;
159   int i;
160   
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");
167 }
168
169 static void 
170 genmacro (f, idx)
171      FILE *f;
172      int idx;
173 {
174   const char *p;
175   int i;
176
177   fprintf (f, "#define gen_rtx_%s%s(mode",
178            (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
179
180   for (p = defs[idx].format, i = 0; *p ; ++p)
181     if (*p != '0')
182       fprintf (f, ", arg%d", i++);
183   fprintf (f, ")   ");
184
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");
190 }
191
192 static void
193 gendef (f, format)
194      FILE *f;
195      const char *format;
196 {
197   const char *p;
198   int i, j;
199   
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++);
204
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++);
209
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);
214
215   fprintf (f, "  PUT_CODE (rt, code);\n");
216   fprintf (f, "  PUT_MODE (rt, mode);\n");
217
218   for (p = format, i = j = 0; *p ; ++p, ++i)
219     if (*p != '0')
220       {
221         fprintf (f, "  %s (rt, %d) = arg%d;\n",
222                  accessor_from_format (*p), i, j++);
223       }
224
225   fprintf (f, "\n  return rt;\n}\n\n");
226 }
227
228 static void
229 genlegend (f)
230      FILE *f;
231 {
232   fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
233   fprintf (f, "   from the RTL description file `rtl.def' */\n\n");
234 }
235
236 static void
237 genheader (f)
238      FILE *f;
239 {
240   int i;
241   const char **fmt;
242
243   for (fmt = formats; *fmt; ++fmt)
244     gendecl (f, *fmt);
245
246   fprintf(f, "\n");
247
248   for (i = 0; i < NUM_RTX_CODE; i++)
249     {
250       if (special_format (defs[i].format))
251         continue;
252       genmacro (f, i);
253     }
254 }
255
256 static void
257 gencode (f)
258      FILE *f;
259 {
260   const char **fmt;
261
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);
273
274   for (fmt = formats; *fmt; ++fmt)
275     gendef (f, *fmt);
276 }
277
278 #if defined(USE_C_ALLOCA)
279 PTR
280 xmalloc (nbytes)
281   size_t nbytes;
282 {
283   register PTR tmp = (PTR) malloc (nbytes);
284
285   if (!tmp)
286     {
287       fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
288                nbytes);
289       exit (FATAL_EXIT_CODE);
290     }
291
292   return tmp;
293 }
294 #endif /* USE_C_ALLOCA */
295
296 int
297 main(argc, argv)
298      int argc;
299      char **argv;
300 {
301   FILE *f;
302
303   if (argc != 3)
304     exit (1);
305
306   find_formats ();
307
308   f = fopen (argv[1], "w");
309   if (f == NULL)
310     {
311       perror(argv[1]);
312       exit (1);
313     }
314   genlegend (f);
315   genheader (f);
316   fclose(f);
317
318   f = fopen (argv[2], "w");
319   if (f == NULL)
320     {
321       perror(argv[2]);
322       exit (1);
323     }
324   genlegend (f);
325   gencode (f);
326   fclose(f);
327
328   exit (0);
329 }