OSDN Git Service

* alpha.c (alpha_initialize_trampoline): Hack around Pmode/ptr_mode
[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           || strcmp (defs[idx].enumname, "MEM") == 0);
134 }
135
136 static void
137 find_formats ()
138 {
139   int i;
140
141   for (i = 0; i < NUM_RTX_CODE; ++i)
142     {
143       const char **f;
144
145       if (special_format (defs[i].format))
146         continue;
147
148       for (f = formats; *f ; ++f)
149         if (!strcmp(*f, defs[i].format))
150           break;
151
152       if (!*f)
153         *f = defs[i].format;
154     }
155 }
156
157 static void
158 gendecl (f, format)
159      FILE *f;
160      const char *format;
161 {
162   const char *p;
163   int i;
164   
165   fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
166            format);
167   for (p = format, i = 0; *p ; ++p)
168     if (*p != '0')
169       fprintf (f, ", %s arg%d", type_from_format (*p), i++);
170   fprintf (f, "));\n");
171 }
172
173 static void 
174 genmacro (f, idx)
175      FILE *f;
176      int idx;
177 {
178   const char *p;
179   int i;
180
181   fprintf (f, "#define gen_rtx_%s%s(mode",
182            (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
183
184   for (p = defs[idx].format, i = 0; *p ; ++p)
185     if (*p != '0')
186       fprintf (f, ", arg%d", i++);
187   fprintf (f, ")   ");
188
189   fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
190   for (p = defs[idx].format, i = 0; *p ; ++p)
191     if (*p != '0')
192       fprintf (f, ",(arg%d)", i++);
193   fprintf (f, ")\n");
194 }
195
196 static void
197 gendef (f, format)
198      FILE *f;
199      const char *format;
200 {
201   const char *p;
202   int i, j;
203   
204   fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
205   for (p = format, i = 0; *p ; ++p)
206     if (*p != '0')
207       fprintf (f, ", arg%d", i++);
208
209   fprintf (f, ")\n     RTX_CODE code;\n     enum machine_mode mode;\n");
210   for (p = format, i = 0; *p ; ++p)
211     if (*p != '0')
212       fprintf (f, "     %s arg%d;\n", type_from_format (*p), i++);
213
214   /* See rtx_alloc in rtl.c for comments.  */
215   fprintf (f, "{\n");
216   fprintf (f, "  rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
217            (int) strlen (format) - 1);
218
219   fprintf (f, "  PUT_CODE (rt, code);\n");
220   fprintf (f, "  PUT_MODE (rt, mode);\n");
221
222   for (p = format, i = j = 0; *p ; ++p, ++i)
223     if (*p != '0')
224       {
225         fprintf (f, "  %s (rt, %d) = arg%d;\n",
226                  accessor_from_format (*p), i, j++);
227       }
228
229   fprintf (f, "\n  return rt;\n}\n\n");
230 }
231
232 static void
233 genlegend (f)
234      FILE *f;
235 {
236   fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
237   fprintf (f, "   from the RTL description file `rtl.def' */\n\n");
238 }
239
240 static void
241 genheader (f)
242      FILE *f;
243 {
244   int i;
245   const char **fmt;
246
247   for (fmt = formats; *fmt; ++fmt)
248     gendecl (f, *fmt);
249
250   fprintf(f, "\n");
251
252   for (i = 0; i < NUM_RTX_CODE; i++)
253     {
254       if (special_format (defs[i].format))
255         continue;
256       genmacro (f, i);
257     }
258 }
259
260 static void
261 gencode (f)
262      FILE *f;
263 {
264   const char **fmt;
265
266   fputs ("#include \"config.h\"\n", f);
267   fputs ("#include \"system.h\"\n", f);
268   fputs ("#include \"obstack.h\"\n", f);
269   fputs ("#include \"rtl.h\"\n\n", f);
270   fputs ("extern struct obstack *rtl_obstack;\n\n", f);
271   fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
272   fputs ("static rtx obstack_alloc_rtx (length)\n", f);
273   fputs ("     register int length;\n{\n", f);
274   fputs ("  rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
275   fputs ("  if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n", f);
276   fputs ("    *(int *)rt = 0;\n", f);
277   fputs ("  else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n", f);
278   fputs ("    *(HOST_WIDE_INT *)rt = 0;\n", f);
279   fputs ("  else\n", f);
280   fputs ("    bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
281   fputs ("  return rt;\n}\n\n", f);
282
283   for (fmt = formats; *fmt; ++fmt)
284     gendef (f, *fmt);
285 }
286
287 #if defined(USE_C_ALLOCA) && !defined(__GNUC__)
288 char *
289 xmalloc (nbytes)
290      int nbytes;
291 {
292   char *tmp = (char *) malloc (nbytes);
293
294   if (!tmp)
295     {
296       fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
297       exit (FATAL_EXIT_CODE);
298     }
299
300   return tmp;
301 }
302 #endif /* USE_C_ALLOCA && !__GNUC__ */
303
304 int
305 main(argc, argv)
306      int argc;
307      char **argv;
308 {
309   FILE *f;
310
311   if (argc != 3)
312     exit (1);
313
314   find_formats ();
315
316   f = fopen (argv[1], "w");
317   if (f == NULL)
318     {
319       perror(argv[1]);
320       exit (1);
321     }
322   genlegend (f);
323   genheader (f);
324   fclose(f);
325
326   f = fopen (argv[2], "w");
327   if (f == NULL)
328     {
329       perror(argv[2]);
330       exit (1);
331     }
332   genlegend (f);
333   gencode (f);
334   fclose(f);
335
336   exit (0);
337 }