OSDN Git Service

* alloca.c: Respect USE_C_ALLOCA.
[pf3gnuchains/gcc-fork.git] / gcc / gengenrtl.c
1 /* Generate code to allocate RTL structures.
2    Copyright (C) 1997 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 ("  if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n", f);
272   fputs ("    *(int *)rt = 0;\n", f);
273   fputs ("  else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n", f);
274   fputs ("    *(HOST_WIDE_INT *)rt = 0;\n", f);
275   fputs ("  else\n", f);
276   fputs ("    bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
277   fputs ("  return rt;\n}\n\n", f);
278
279   for (fmt = formats; *fmt; ++fmt)
280     gendef (f, *fmt);
281 }
282
283 #if defined(USE_C_ALLOCA)
284 char *
285 xmalloc (nbytes)
286      int nbytes;
287 {
288   char *tmp = (char *) malloc (nbytes);
289
290   if (!tmp)
291     {
292       fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
293                nbytes);
294       exit (FATAL_EXIT_CODE);
295     }
296
297   return tmp;
298 }
299 #endif /* USE_C_ALLOCA */
300
301 int
302 main(argc, argv)
303      int argc;
304      char **argv;
305 {
306   FILE *f;
307
308   if (argc != 3)
309     exit (1);
310
311   find_formats ();
312
313   f = fopen (argv[1], "w");
314   if (f == NULL)
315     {
316       perror(argv[1]);
317       exit (1);
318     }
319   genlegend (f);
320   genheader (f);
321   fclose(f);
322
323   f = fopen (argv[2], "w");
324   if (f == NULL)
325     {
326       perror(argv[2]);
327       exit (1);
328     }
329   genlegend (f);
330   gencode (f);
331   fclose(f);
332
333   exit (0);
334 }