]> gcc.gnu.org Git - gcc.git/blame - gcc/gengenrtl.c
rtl.c: Define CONST_DOUBLE_FORMAT to the appropriate format for a CONST_DOUBLE...
[gcc.git] / gcc / gengenrtl.c
CommitLineData
3b80f6ca 1/* Generate code to allocate RTL structures.
0133b7d9 2 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
3b80f6ca
RH
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include "hconfig.h"
b04cd507 23#include "system.h"
3b80f6ca 24
3b80f6ca
RH
25#define NO_GENRTL_H
26#include "rtl.h"
987009bf 27#undef abort
3b80f6ca 28
aa0b4465
ZW
29#include "real.h"
30
31/* Calculate the format for CONST_DOUBLE. This depends on the relative
32 widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
33 We only need to go out to e0wwww, since min(HOST_WIDE_INT)==32 and
34 max(LONG_DOUBLE_TYPE_SIZE)==128.
35 This is duplicated in rtl.c.
36 A number of places assume that there are always at least two 'w'
37 slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
38#if HOST_BITS_PER_WIDE_INT >= LONG_DOUBLE_TYPE_SIZE
39#define CONST_DOUBLE_FORMAT "e0ww"
40#elif HOST_BITS_PER_WIDE_INT*2 >= LONG_DOUBLE_TYPE_SIZE
41#define CONST_DOUBLE_FORMAT "e0ww"
42#elif HOST_BITS_PER_WIDE_INT*3 >= LONG_DOUBLE_TYPE_SIZE
43#define CONST_DOUBLE_FORMAT "e0www"
44#elif HOST_BITS_PER_WIDE_INT*4 >= LONG_DOUBLE_TYPE_SIZE
45#define CONST_DOUBLE_FORMAT "e0wwww"
46#else
47#define CONST_DOUBLE_FORMAT /* nothing - will cause syntax error */
48#endif
49
3b80f6ca
RH
50
51struct rtx_definition
52{
53 const char *enumname, *name, *format;
54};
55
d4ba0ead 56#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
3b80f6ca
RH
57
58struct rtx_definition defs[] =
59{
60#include "rtl.def" /* rtl expressions are documented here */
61};
62
63const char *formats[NUM_RTX_CODE];
64
fd97443c
KG
65static const char *type_from_format PROTO((int));
66static const char *accessor_from_format PROTO((int));
56c0e996
BS
67static int special_format PROTO((const char *));
68static int special_rtx PROTO((int));
69static void find_formats PROTO((void));
70static void gendecl PROTO((FILE *, const char *));
71static void genmacro PROTO((FILE *, int));
72static void gendef PROTO((FILE *, const char *));
73static void genlegend PROTO((FILE *));
74static void genheader PROTO((FILE *));
75static void gencode PROTO((FILE *));
76
0133b7d9
RH
77/* Decode a format letter into a C type string. */
78
3b80f6ca 79static const char *
982255c8 80type_from_format (c)
fd97443c 81 int c;
3b80f6ca
RH
82{
83 switch (c)
84 {
85 case 'i':
86 return "int";
87 case 'w':
88 return "HOST_WIDE_INT";
89 case 's':
90 return "char *";
91 case 'e':
92 case 'u':
93 return "rtx";
94 case 'E':
95 return "rtvec";
0dfa1860 96 case 'b':
8f985ec4 97 return "struct bitmap_head_def *"; /* bitmap - typedef not available */
0dfa1860 98 case 't':
8f985ec4 99 return "union tree_node *"; /* tree - typedef not available */
3b80f6ca
RH
100 default:
101 abort ();
102 }
103}
104
0133b7d9
RH
105/* Decode a format letter into the proper accessor function. */
106
3b80f6ca 107static const char *
982255c8 108accessor_from_format (c)
fd97443c 109 int c;
3b80f6ca
RH
110{
111 switch (c)
112 {
113 case 'i':
114 return "XINT";
115 case 'w':
116 return "XWINT";
117 case 's':
118 return "XSTR";
119 case 'e':
120 case 'u':
121 return "XEXP";
122 case 'E':
123 return "XVEC";
0dfa1860
MM
124 case 'b':
125 return "XBITMAP";
126 case 't':
127 return "XTREE";
3b80f6ca
RH
128 default:
129 abort ();
130 }
131}
132
0133b7d9
RH
133/* Return true if a format character doesn't need normal processing. */
134
3b80f6ca
RH
135static int
136special_format (fmt)
137 const char *fmt;
138{
139 return (strchr (fmt, '*') != 0
140 || strchr (fmt, 'V') != 0
141 || strchr (fmt, 'S') != 0
142 || strchr (fmt, 'n') != 0);
143}
144
0133b7d9
RH
145/* Return true if an rtx requires special processing. */
146
3b80f6ca
RH
147static int
148special_rtx (idx)
149 int idx;
150{
151 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
0133b7d9 152 || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
41472af8
MM
153 || strcmp (defs[idx].enumname, "REG") == 0
154 || strcmp (defs[idx].enumname, "MEM") == 0);
3b80f6ca
RH
155}
156
0133b7d9
RH
157/* Fill `formats' with all unique format strings. */
158
3b80f6ca
RH
159static void
160find_formats ()
161{
162 int i;
163
164 for (i = 0; i < NUM_RTX_CODE; ++i)
165 {
166 const char **f;
167
168 if (special_format (defs[i].format))
169 continue;
170
171 for (f = formats; *f ; ++f)
0133b7d9 172 if (! strcmp (*f, defs[i].format))
3b80f6ca
RH
173 break;
174
175 if (!*f)
176 *f = defs[i].format;
177 }
178}
179
0133b7d9
RH
180/* Emit a prototype for the rtx generator for a format. */
181
3b80f6ca
RH
182static void
183gendecl (f, format)
184 FILE *f;
185 const char *format;
186{
187 const char *p;
188 int i;
189
190 fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
191 format);
192 for (p = format, i = 0; *p ; ++p)
193 if (*p != '0')
194 fprintf (f, ", %s arg%d", type_from_format (*p), i++);
195 fprintf (f, "));\n");
196}
197
0133b7d9
RH
198/* Emit a define mapping an rtx code to the generator for its format. */
199
3b80f6ca
RH
200static void
201genmacro (f, idx)
202 FILE *f;
203 int idx;
204{
205 const char *p;
206 int i;
207
208 fprintf (f, "#define gen_rtx_%s%s(mode",
209 (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
210
211 for (p = defs[idx].format, i = 0; *p ; ++p)
212 if (*p != '0')
213 fprintf (f, ", arg%d", i++);
214 fprintf (f, ") ");
215
216 fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
217 for (p = defs[idx].format, i = 0; *p ; ++p)
218 if (*p != '0')
219 fprintf (f, ",(arg%d)", i++);
220 fprintf (f, ")\n");
221}
222
0133b7d9
RH
223/* Emit the implementation for the rtx generator for a format. */
224
3b80f6ca
RH
225static void
226gendef (f, format)
227 FILE *f;
228 const char *format;
229{
230 const char *p;
231 int i, j;
232
233 fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
234 for (p = format, i = 0; *p ; ++p)
235 if (*p != '0')
236 fprintf (f, ", arg%d", i++);
237
238 fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
239 for (p = format, i = 0; *p ; ++p)
240 if (*p != '0')
241 fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
242
243 /* See rtx_alloc in rtl.c for comments. */
244 fprintf (f, "{\n");
4b8140a6
JC
245 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
246 (int) strlen (format) - 1);
3b80f6ca
RH
247
248 fprintf (f, " PUT_CODE (rt, code);\n");
249 fprintf (f, " PUT_MODE (rt, mode);\n");
250
251 for (p = format, i = j = 0; *p ; ++p, ++i)
252 if (*p != '0')
253 {
254 fprintf (f, " %s (rt, %d) = arg%d;\n",
255 accessor_from_format (*p), i, j++);
256 }
257
258 fprintf (f, "\n return rt;\n}\n\n");
259}
260
0133b7d9
RH
261/* Emit the `do not edit' banner. */
262
3b80f6ca
RH
263static void
264genlegend (f)
265 FILE *f;
266{
0133b7d9
RH
267 fputs ("/* Generated automaticaly by the program `gengenrtl'\n", f);
268 fputs (" from the RTL description file `rtl.def' */\n\n", f);
3b80f6ca
RH
269}
270
0133b7d9
RH
271/* Emit "genrtl.h". */
272
3b80f6ca
RH
273static void
274genheader (f)
275 FILE *f;
276{
277 int i;
278 const char **fmt;
279
280 for (fmt = formats; *fmt; ++fmt)
281 gendecl (f, *fmt);
282
0133b7d9 283 fprintf (f, "\n");
3b80f6ca
RH
284
285 for (i = 0; i < NUM_RTX_CODE; i++)
286 {
287 if (special_format (defs[i].format))
288 continue;
289 genmacro (f, i);
290 }
291}
292
0133b7d9
RH
293/* Emit "genrtl.c". */
294
3b80f6ca
RH
295static void
296gencode (f)
297 FILE *f;
298{
299 const char **fmt;
300
4b8140a6 301 fputs ("#include \"config.h\"\n", f);
560bd19e 302 fputs ("#include \"system.h\"\n", f);
4b8140a6
JC
303 fputs ("#include \"obstack.h\"\n", f);
304 fputs ("#include \"rtl.h\"\n\n", f);
305 fputs ("extern struct obstack *rtl_obstack;\n\n", f);
306 fputs ("static rtx obstack_alloc_rtx PROTO((int length));\n", f);
307 fputs ("static rtx obstack_alloc_rtx (length)\n", f);
308 fputs (" register int length;\n{\n", f);
309 fputs (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n", f);
0133b7d9 310 fputs (" memset(rt, 0, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
4b8140a6 311 fputs (" return rt;\n}\n\n", f);
3b80f6ca
RH
312
313 for (fmt = formats; *fmt; ++fmt)
314 gendef (f, *fmt);
315}
316
402cdad5 317#if defined(USE_C_ALLOCA)
2778b98d 318PTR
982255c8 319xmalloc (nbytes)
2778b98d 320 size_t nbytes;
982255c8 321{
2778b98d 322 register PTR tmp = (PTR) malloc (nbytes);
982255c8
KG
323
324 if (!tmp)
325 {
402cdad5
RH
326 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
327 nbytes);
982255c8
KG
328 exit (FATAL_EXIT_CODE);
329 }
330
331 return tmp;
332}
402cdad5 333#endif /* USE_C_ALLOCA */
982255c8 334
3b80f6ca
RH
335int
336main(argc, argv)
337 int argc;
338 char **argv;
339{
340 FILE *f;
341
342 if (argc != 3)
343 exit (1);
344
345 find_formats ();
346
347 f = fopen (argv[1], "w");
348 if (f == NULL)
349 {
0133b7d9 350 perror (argv[1]);
3b80f6ca
RH
351 exit (1);
352 }
353 genlegend (f);
354 genheader (f);
0133b7d9 355 fclose (f);
3b80f6ca
RH
356
357 f = fopen (argv[2], "w");
358 if (f == NULL)
359 {
0133b7d9 360 perror (argv[2]);
3b80f6ca
RH
361 exit (1);
362 }
363 genlegend (f);
364 gencode (f);
0133b7d9 365 fclose (f);
3b80f6ca
RH
366
367 exit (0);
368}
This page took 0.382927 seconds and 5 git commands to generate.