]>
Commit | Line | Data |
---|---|---|
3b80f6ca RH |
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" | |
b04cd507 | 23 | #include "system.h" |
3b80f6ca RH |
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 | ||
d4ba0ead | 38 | #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT }, |
3b80f6ca RH |
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 | ||
56c0e996 BS |
47 | static const char *type_from_format PROTO((char)); |
48 | static const char *accessor_from_format PROTO((char)); | |
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 | ||
3b80f6ca | 59 | static const char * |
982255c8 KG |
60 | type_from_format (c) |
61 | char c; | |
3b80f6ca RH |
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 | default: | |
77 | abort (); | |
78 | } | |
79 | } | |
80 | ||
81 | static const char * | |
982255c8 KG |
82 | accessor_from_format (c) |
83 | char c; | |
3b80f6ca RH |
84 | { |
85 | switch (c) | |
86 | { | |
87 | case 'i': | |
88 | return "XINT"; | |
89 | case 'w': | |
90 | return "XWINT"; | |
91 | case 's': | |
92 | return "XSTR"; | |
93 | case 'e': | |
94 | case 'u': | |
95 | return "XEXP"; | |
96 | case 'E': | |
97 | return "XVEC"; | |
98 | default: | |
99 | abort (); | |
100 | } | |
101 | } | |
102 | ||
103 | static int | |
104 | special_format (fmt) | |
105 | const char *fmt; | |
106 | { | |
107 | return (strchr (fmt, '*') != 0 | |
108 | || strchr (fmt, 'V') != 0 | |
109 | || strchr (fmt, 'S') != 0 | |
110 | || strchr (fmt, 'n') != 0); | |
111 | } | |
112 | ||
113 | static int | |
114 | special_rtx (idx) | |
115 | int idx; | |
116 | { | |
117 | return (strcmp (defs[idx].enumname, "CONST_INT") == 0 | |
118 | || strcmp (defs[idx].enumname, "REG") == 0); | |
119 | } | |
120 | ||
121 | static void | |
122 | find_formats () | |
123 | { | |
124 | int i; | |
125 | ||
126 | for (i = 0; i < NUM_RTX_CODE; ++i) | |
127 | { | |
128 | const char **f; | |
129 | ||
130 | if (special_format (defs[i].format)) | |
131 | continue; | |
132 | ||
133 | for (f = formats; *f ; ++f) | |
134 | if (!strcmp(*f, defs[i].format)) | |
135 | break; | |
136 | ||
137 | if (!*f) | |
138 | *f = defs[i].format; | |
139 | } | |
140 | } | |
141 | ||
142 | static void | |
143 | gendecl (f, format) | |
144 | FILE *f; | |
145 | const char *format; | |
146 | { | |
147 | const char *p; | |
148 | int i; | |
149 | ||
150 | fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode", | |
151 | format); | |
152 | for (p = format, i = 0; *p ; ++p) | |
153 | if (*p != '0') | |
154 | fprintf (f, ", %s arg%d", type_from_format (*p), i++); | |
155 | fprintf (f, "));\n"); | |
156 | } | |
157 | ||
158 | static void | |
159 | genmacro (f, idx) | |
160 | FILE *f; | |
161 | int idx; | |
162 | { | |
163 | const char *p; | |
164 | int i; | |
165 | ||
166 | fprintf (f, "#define gen_rtx_%s%s(mode", | |
167 | (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname); | |
168 | ||
169 | for (p = defs[idx].format, i = 0; *p ; ++p) | |
170 | if (*p != '0') | |
171 | fprintf (f, ", arg%d", i++); | |
172 | fprintf (f, ") "); | |
173 | ||
174 | fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname); | |
175 | for (p = defs[idx].format, i = 0; *p ; ++p) | |
176 | if (*p != '0') | |
177 | fprintf (f, ",(arg%d)", i++); | |
178 | fprintf (f, ")\n"); | |
179 | } | |
180 | ||
181 | static void | |
182 | gendef (f, format) | |
183 | FILE *f; | |
184 | const char *format; | |
185 | { | |
186 | const char *p; | |
187 | int i, j; | |
188 | ||
189 | fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format); | |
190 | for (p = format, i = 0; *p ; ++p) | |
191 | if (*p != '0') | |
192 | fprintf (f, ", arg%d", i++); | |
193 | ||
194 | fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n"); | |
195 | for (p = format, i = 0; *p ; ++p) | |
196 | if (*p != '0') | |
197 | fprintf (f, " %s arg%d;\n", type_from_format (*p), i++); | |
198 | ||
199 | /* See rtx_alloc in rtl.c for comments. */ | |
200 | fprintf (f, "{\n"); | |
4b8140a6 JC |
201 | fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n", |
202 | (int) strlen (format) - 1); | |
3b80f6ca RH |
203 | |
204 | fprintf (f, " PUT_CODE (rt, code);\n"); | |
205 | fprintf (f, " PUT_MODE (rt, mode);\n"); | |
206 | ||
207 | for (p = format, i = j = 0; *p ; ++p, ++i) | |
208 | if (*p != '0') | |
209 | { | |
210 | fprintf (f, " %s (rt, %d) = arg%d;\n", | |
211 | accessor_from_format (*p), i, j++); | |
212 | } | |
213 | ||
214 | fprintf (f, "\n return rt;\n}\n\n"); | |
215 | } | |
216 | ||
217 | static void | |
218 | genlegend (f) | |
219 | FILE *f; | |
220 | { | |
221 | fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n"); | |
222 | fprintf (f, " from the RTL description file `rtl.def' */\n\n"); | |
223 | } | |
224 | ||
225 | static void | |
226 | genheader (f) | |
227 | FILE *f; | |
228 | { | |
229 | int i; | |
230 | const char **fmt; | |
231 | ||
232 | for (fmt = formats; *fmt; ++fmt) | |
233 | gendecl (f, *fmt); | |
234 | ||
235 | fprintf(f, "\n"); | |
236 | ||
237 | for (i = 0; i < NUM_RTX_CODE; i++) | |
238 | { | |
239 | if (special_format (defs[i].format)) | |
240 | continue; | |
241 | genmacro (f, i); | |
242 | } | |
243 | } | |
244 | ||
245 | static void | |
246 | gencode (f) | |
247 | FILE *f; | |
248 | { | |
249 | const char **fmt; | |
250 | ||
4b8140a6 | 251 | fputs ("#include \"config.h\"\n", f); |
560bd19e | 252 | fputs ("#include \"system.h\"\n", f); |
4b8140a6 JC |
253 | fputs ("#include \"obstack.h\"\n", f); |
254 | fputs ("#include \"rtl.h\"\n\n", f); | |
255 | fputs ("extern struct obstack *rtl_obstack;\n\n", f); | |
256 | fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f); | |
257 | fputs ("static rtx obstack_alloc_rtx (length)\n", f); | |
258 | fputs (" register int length;\n{\n", f); | |
259 | fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f); | |
260 | fputs (" if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n", f); | |
261 | fputs (" *(int *)rt = 0;\n", f); | |
262 | fputs (" else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n", f); | |
263 | fputs (" *(HOST_WIDE_INT *)rt = 0;\n", f); | |
264 | fputs (" else\n", f); | |
d6f4ec51 | 265 | fputs (" bzero((char *) rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f); |
4b8140a6 | 266 | fputs (" return rt;\n}\n\n", f); |
3b80f6ca RH |
267 | |
268 | for (fmt = formats; *fmt; ++fmt) | |
269 | gendef (f, *fmt); | |
270 | } | |
271 | ||
982255c8 KG |
272 | #if defined(USE_C_ALLOCA) && !defined(__GNUC__) |
273 | char * | |
274 | xmalloc (nbytes) | |
275 | int nbytes; | |
276 | { | |
277 | char *tmp = (char *) malloc (nbytes); | |
278 | ||
279 | if (!tmp) | |
280 | { | |
281 | fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); | |
282 | exit (FATAL_EXIT_CODE); | |
283 | } | |
284 | ||
285 | return tmp; | |
286 | } | |
287 | #endif /* USE_C_ALLOCA && !__GNUC__ */ | |
288 | ||
3b80f6ca RH |
289 | int |
290 | main(argc, argv) | |
291 | int argc; | |
292 | char **argv; | |
293 | { | |
294 | FILE *f; | |
295 | ||
296 | if (argc != 3) | |
297 | exit (1); | |
298 | ||
299 | find_formats (); | |
300 | ||
301 | f = fopen (argv[1], "w"); | |
302 | if (f == NULL) | |
303 | { | |
304 | perror(argv[1]); | |
305 | exit (1); | |
306 | } | |
307 | genlegend (f); | |
308 | genheader (f); | |
309 | fclose(f); | |
310 | ||
311 | f = fopen (argv[2], "w"); | |
312 | if (f == NULL) | |
313 | { | |
314 | perror(argv[2]); | |
315 | exit (1); | |
316 | } | |
317 | genlegend (f); | |
318 | gencode (f); | |
319 | fclose(f); | |
320 | ||
321 | exit (0); | |
322 | } |