OSDN Git Service

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