Move *-*-gnu* pattern below *-*-linux*.
[official-gcc.git] / gcc / gengenrtl.c
blob762c96fa4e42e398b8e043172ed9433c74682b78
1 /* Generate code to allocate RTL structures.
2 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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.
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.
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. */
22 #include "hconfig.h"
23 #include "system.h"
25 #define NO_GENRTL_H
26 #include "rtl.h"
27 #undef abort
29 #include "real.h"
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
51 struct rtx_definition
53 const char *enumname, *name, *format;
56 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
58 struct rtx_definition defs[] =
60 #include "rtl.def" /* rtl expressions are documented here */
63 const char *formats[NUM_RTX_CODE];
65 static const char *type_from_format PROTO((int));
66 static const char *accessor_from_format PROTO((int));
67 static int special_format PROTO((const char *));
68 static int special_rtx PROTO((int));
69 static void find_formats PROTO((void));
70 static void gendecl PROTO((FILE *, const char *));
71 static void genmacro PROTO((FILE *, int));
72 static void gendef PROTO((FILE *, const char *));
73 static void genlegend PROTO((FILE *));
74 static void genheader PROTO((FILE *));
75 static void gencode PROTO((FILE *));
77 /* Decode a format letter into a C type string. */
79 static const char *
80 type_from_format (c)
81 int c;
83 switch (c)
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";
96 case 'b':
97 return "struct bitmap_head_def *"; /* bitmap - typedef not available */
98 case 't':
99 return "union tree_node *"; /* tree - typedef not available */
100 default:
101 abort ();
105 /* Decode a format letter into the proper accessor function. */
107 static const char *
108 accessor_from_format (c)
109 int c;
111 switch (c)
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";
124 case 'b':
125 return "XBITMAP";
126 case 't':
127 return "XTREE";
128 default:
129 abort ();
133 /* Return true if a format character doesn't need normal processing. */
135 static int
136 special_format (fmt)
137 const char *fmt;
139 return (strchr (fmt, '*') != 0
140 || strchr (fmt, 'V') != 0
141 || strchr (fmt, 'S') != 0
142 || strchr (fmt, 'n') != 0);
145 /* Return true if an rtx requires special processing. */
147 static int
148 special_rtx (idx)
149 int idx;
151 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
152 || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
153 || strcmp (defs[idx].enumname, "REG") == 0
154 || strcmp (defs[idx].enumname, "MEM") == 0);
157 /* Fill `formats' with all unique format strings. */
159 static void
160 find_formats ()
162 int i;
164 for (i = 0; i < NUM_RTX_CODE; ++i)
166 const char **f;
168 if (special_format (defs[i].format))
169 continue;
171 for (f = formats; *f ; ++f)
172 if (! strcmp (*f, defs[i].format))
173 break;
175 if (!*f)
176 *f = defs[i].format;
180 /* Emit a prototype for the rtx generator for a format. */
182 static void
183 gendecl (f, format)
184 FILE *f;
185 const char *format;
187 const char *p;
188 int i;
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");
198 /* Emit a define mapping an rtx code to the generator for its format. */
200 static void
201 genmacro (f, idx)
202 FILE *f;
203 int idx;
205 const char *p;
206 int i;
208 fprintf (f, "#define gen_rtx_%s%s(mode",
209 (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
211 for (p = defs[idx].format, i = 0; *p ; ++p)
212 if (*p != '0')
213 fprintf (f, ", arg%d", i++);
214 fprintf (f, ") ");
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");
223 /* Emit the implementation for the rtx generator for a format. */
225 static void
226 gendef (f, format)
227 FILE *f;
228 const char *format;
230 const char *p;
231 int i, j;
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++);
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++);
243 /* See rtx_alloc in rtl.c for comments. */
244 fprintf (f, "{\n");
245 fprintf (f, " rtx rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
246 (int) strlen (format) - 1);
248 fprintf (f, " PUT_CODE (rt, code);\n");
249 fprintf (f, " PUT_MODE (rt, mode);\n");
251 for (p = format, i = j = 0; *p ; ++p, ++i)
252 if (*p != '0')
254 fprintf (f, " %s (rt, %d) = arg%d;\n",
255 accessor_from_format (*p), i, j++);
258 fprintf (f, "\n return rt;\n}\n\n");
261 /* Emit the `do not edit' banner. */
263 static void
264 genlegend (f)
265 FILE *f;
267 fputs ("/* Generated automaticaly by the program `gengenrtl'\n", f);
268 fputs (" from the RTL description file `rtl.def' */\n\n", f);
271 /* Emit "genrtl.h". */
273 static void
274 genheader (f)
275 FILE *f;
277 int i;
278 const char **fmt;
280 for (fmt = formats; *fmt; ++fmt)
281 gendecl (f, *fmt);
283 fprintf (f, "\n");
285 for (i = 0; i < NUM_RTX_CODE; i++)
287 if (special_format (defs[i].format))
288 continue;
289 genmacro (f, i);
293 /* Emit "genrtl.c". */
295 static void
296 gencode (f)
297 FILE *f;
299 const char **fmt;
301 fputs ("#include \"config.h\"\n", f);
302 fputs ("#include \"system.h\"\n", f);
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);
310 fputs (" memset(rt, 0, sizeof(struct rtx_def) - sizeof(rtunion));\n\n", f);
311 fputs (" return rt;\n}\n\n", f);
313 for (fmt = formats; *fmt; ++fmt)
314 gendef (f, *fmt);
317 #if defined(USE_C_ALLOCA)
319 xmalloc (nbytes)
320 size_t nbytes;
322 register PTR tmp = (PTR) malloc (nbytes);
324 if (!tmp)
326 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
327 nbytes);
328 exit (FATAL_EXIT_CODE);
331 return tmp;
333 #endif /* USE_C_ALLOCA */
336 main(argc, argv)
337 int argc;
338 char **argv;
340 FILE *f;
342 if (argc != 3)
343 exit (1);
345 find_formats ();
347 f = fopen (argv[1], "w");
348 if (f == NULL)
350 perror (argv[1]);
351 exit (1);
353 genlegend (f);
354 genheader (f);
355 fclose (f);
357 f = fopen (argv[2], "w");
358 if (f == NULL)
360 perror (argv[2]);
361 exit (1);
363 genlegend (f);
364 gencode (f);
365 fclose (f);
367 exit (0);