]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gengenrtl.c
gcc-dg.exp (dg-xfail-if): Fix thinko.
[thirdparty/gcc.git] / gcc / gengenrtl.c
CommitLineData
3b80f6ca 1/* Generate code to allocate RTL structures.
3d7aafde
AJ
2 Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
3 Free Software Foundation, Inc.
3b80f6ca 4
1322177d 5This file is part of GCC.
3b80f6ca 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
3b80f6ca 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
3b80f6ca
RH
16
17You should have received a copy of the GNU General Public License
1322177d
LB
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
3b80f6ca
RH
21
22
4977bab6 23#include "bconfig.h"
b04cd507 24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
3b80f6ca 27
3b80f6ca
RH
28#define NO_GENRTL_H
29#include "rtl.h"
987009bf 30#undef abort
3b80f6ca 31
aa0b4465
ZW
32#include "real.h"
33
8f9eb495 34struct rtx_definition
3b80f6ca 35{
8b60264b 36 const char *const enumname, *const name, *const format;
3b80f6ca
RH
37};
38
4bc5fbd4 39#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGX(ENUM), NAME, FORMAT },
3b80f6ca 40
8f9eb495
AJ
41static const struct rtx_definition defs[] =
42{
3b80f6ca
RH
43#include "rtl.def" /* rtl expressions are documented here */
44};
45
0b5826ac 46static const char *formats[NUM_RTX_CODE];
3b80f6ca 47
3d7aafde
AJ
48static const char *type_from_format (int);
49static const char *accessor_from_format (int);
50static int special_format (const char *);
51static int special_rtx (int);
52static int excluded_rtx (int);
53static void find_formats (void);
54static void gendecl (const char *);
55static void genmacro (int);
56static void gendef (const char *);
57static void genlegend (void);
58static void genheader (void);
59static void gencode (void);
c5c76735 60\f
0133b7d9
RH
61/* Decode a format letter into a C type string. */
62
3b80f6ca 63static const char *
3d7aafde 64type_from_format (int c)
3b80f6ca
RH
65{
66 switch (c)
67 {
68 case 'i':
c5c76735
JL
69 return "int ";
70
3b80f6ca 71 case 'w':
c5c76735
JL
72 return "HOST_WIDE_INT ";
73
3b80f6ca 74 case 's':
3cce094d 75 return "const char *";
c5c76735
JL
76
77 case 'e': case 'u':
78 return "rtx ";
79
3b80f6ca 80 case 'E':
c5c76735 81 return "rtvec ";
0dfa1860 82 case 'b':
8f985ec4 83 return "struct bitmap_head_def *"; /* bitmap - typedef not available */
0dfa1860 84 case 't':
8f985ec4 85 return "union tree_node *"; /* tree - typedef not available */
c8ea9a0f
JH
86 case 'B':
87 return "struct basic_block_def *"; /* basic block - typedef not available */
3b80f6ca
RH
88 default:
89 abort ();
90 }
91}
92
0133b7d9
RH
93/* Decode a format letter into the proper accessor function. */
94
3b80f6ca 95static const char *
3d7aafde 96accessor_from_format (int c)
3b80f6ca
RH
97{
98 switch (c)
99 {
100 case 'i':
101 return "XINT";
c5c76735 102
3b80f6ca
RH
103 case 'w':
104 return "XWINT";
c5c76735 105
3b80f6ca
RH
106 case 's':
107 return "XSTR";
c5c76735
JL
108
109 case 'e': case 'u':
3b80f6ca 110 return "XEXP";
c5c76735 111
3b80f6ca
RH
112 case 'E':
113 return "XVEC";
c5c76735 114
0dfa1860
MM
115 case 'b':
116 return "XBITMAP";
c5c76735 117
0dfa1860
MM
118 case 't':
119 return "XTREE";
c5c76735 120
c8ea9a0f
JH
121 case 'B':
122 return "XBBDEF";
10d1bb36
JH
123
124 default:
125 abort ();
3b80f6ca
RH
126 }
127}
128
c5c76735
JL
129/* Return nonzero if we should ignore FMT, an RTL format, when making
130 the list of formats we write routines to create. */
0133b7d9 131
3b80f6ca 132static int
3d7aafde 133special_format (const char *fmt)
3b80f6ca
RH
134{
135 return (strchr (fmt, '*') != 0
136 || strchr (fmt, 'V') != 0
137 || strchr (fmt, 'S') != 0
138 || strchr (fmt, 'n') != 0);
139}
140
5692c7bc
ZW
141/* Return nonzero if the RTL code given by index IDX is one that we should
142 generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
143 is a wrapper in emit-rtl.c). */
0133b7d9 144
3b80f6ca 145static int
3d7aafde 146special_rtx (int idx)
3b80f6ca
RH
147{
148 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
41472af8 149 || strcmp (defs[idx].enumname, "REG") == 0
ddef6bc7 150 || strcmp (defs[idx].enumname, "SUBREG") == 0
a06e3c40
R
151 || strcmp (defs[idx].enumname, "MEM") == 0
152 || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
3b80f6ca
RH
153}
154
5692c7bc
ZW
155/* Return nonzero if the RTL code given by index IDX is one that we should
156 generate no macro for at all (because gen_rtx_FOO is never used or
157 cannot have the obvious interface). */
158
159static int
3d7aafde 160excluded_rtx (int idx)
5692c7bc
ZW
161{
162 return (strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0);
163}
164
dc297297 165/* Place a list of all format specifiers we use into the array FORMAT. */
0133b7d9 166
3b80f6ca 167static void
3d7aafde 168find_formats (void)
3b80f6ca
RH
169{
170 int i;
171
c5c76735 172 for (i = 0; i < NUM_RTX_CODE; i++)
3b80f6ca
RH
173 {
174 const char **f;
175
176 if (special_format (defs[i].format))
177 continue;
178
c5c76735 179 for (f = formats; *f; f++)
0133b7d9 180 if (! strcmp (*f, defs[i].format))
3b80f6ca
RH
181 break;
182
c5c76735 183 if (*f == 0)
3b80f6ca
RH
184 *f = defs[i].format;
185 }
186}
187
c5c76735 188/* Write the declarations for the routine to allocate RTL with FORMAT. */
0133b7d9 189
3b80f6ca 190static void
3d7aafde 191gendecl (const char *format)
3b80f6ca
RH
192{
193 const char *p;
c5c76735 194 int i, pos;
8f9eb495 195
3d7aafde 196 printf ("extern rtx gen_rtx_fmt_%s\t (RTX_CODE, ", format);
c5c76735
JL
197 printf ("enum machine_mode mode");
198
199 /* Write each parameter that is needed and start a new line when the line
200 would overflow. */
201 for (p = format, i = 0, pos = 75; *p != 0; p++)
3b80f6ca 202 if (*p != '0')
c5c76735
JL
203 {
204 int ourlen = strlen (type_from_format (*p)) + 6 + (i > 9);
205
206 printf (",");
207 if (pos + ourlen > 76)
208 printf ("\n\t\t\t\t "), pos = 39;
209
210 printf (" %sarg%d", type_from_format (*p), i++);
211 pos += ourlen;
212 }
213
3d7aafde 214 printf (");\n");
3b80f6ca
RH
215}
216
c5c76735
JL
217/* Generate macros to generate RTL of code IDX using the functions we
218 write. */
0133b7d9 219
8f9eb495 220static void
3d7aafde 221genmacro (int idx)
3b80f6ca
RH
222{
223 const char *p;
224 int i;
225
c5c76735
JL
226 /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
227 gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */
3b80f6ca 228
5692c7bc
ZW
229 if (excluded_rtx (idx))
230 /* Don't define a macro for this code. */
231 return;
232
c5c76735
JL
233 printf ("#define gen_rtx_%s%s(MODE",
234 special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
235
236 for (p = defs[idx].format, i = 0; *p != 0; p++)
3b80f6ca 237 if (*p != '0')
c5c76735
JL
238 printf (", ARG%d", i++);
239
240 printf (") \\\n gen_rtx_fmt_%s (%s, (MODE)",
241 defs[idx].format, defs[idx].enumname);
3b80f6ca 242
c5c76735 243 for (p = defs[idx].format, i = 0; *p != 0; p++)
3b80f6ca 244 if (*p != '0')
c5c76735
JL
245 printf (", (ARG%d)", i++);
246
f8a83ee3 247 puts (")");
3b80f6ca
RH
248}
249
c5c76735
JL
250/* Generate the code for the function to generate RTL whose
251 format is FORMAT. */
0133b7d9 252
3b80f6ca 253static void
3d7aafde 254gendef (const char *format)
3b80f6ca
RH
255{
256 const char *p;
257 int i, j;
8f9eb495 258
c5c76735
JL
259 /* Start by writing the definition of the function name and the types
260 of the arguments. */
3b80f6ca 261
c5c76735
JL
262 printf ("rtx\ngen_rtx_fmt_%s (code, mode", format);
263 for (p = format, i = 0; *p != 0; p++)
3b80f6ca 264 if (*p != '0')
c5c76735 265 printf (", arg%d", i++);
3b80f6ca 266
f8a83ee3 267 puts (")\n RTX_CODE code;\n enum machine_mode mode;");
c5c76735
JL
268 for (p = format, i = 0; *p != 0; p++)
269 if (*p != '0')
270 printf (" %sarg%d;\n", type_from_format (*p), i++);
271
272 /* Now write out the body of the function itself, which allocates
273 the memory and initializes it. */
f8a83ee3
ZW
274 puts ("{");
275 puts (" rtx rt;");
1f8f4a0b 276 printf (" rt = ggc_alloc_rtx (%d);\n", (int) strlen (format));
f8a83ee3
ZW
277
278 puts (" memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));\n");
279 puts (" PUT_CODE (rt, code);");
280 puts (" PUT_MODE (rt, mode);");
3b80f6ca
RH
281
282 for (p = format, i = j = 0; *p ; ++p, ++i)
283 if (*p != '0')
c5c76735 284 printf (" %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
f8a83ee3
ZW
285 else
286 printf (" X0EXP (rt, %d) = NULL_RTX;\n", i);
3b80f6ca 287
f8a83ee3 288 puts ("\n return rt;\n}\n");
3b80f6ca
RH
289}
290
c5c76735 291/* Generate the documentation header for files we write. */
0133b7d9 292
3b80f6ca 293static void
3d7aafde 294genlegend (void)
3b80f6ca 295{
f8a83ee3 296 puts ("/* Generated automatically by gengenrtl from rtl.def. */\n");
3b80f6ca
RH
297}
298
c5c76735 299/* Generate the text of the header file we make, genrtl.h. */
0133b7d9 300
3b80f6ca 301static void
3d7aafde 302genheader (void)
3b80f6ca
RH
303{
304 int i;
305 const char **fmt;
0313e85b
ZW
306
307 puts ("#ifndef GCC_GENRTL_H");
308 puts ("#define GCC_GENRTL_H\n");
309
3b80f6ca 310 for (fmt = formats; *fmt; ++fmt)
c5c76735 311 gendecl (*fmt);
3b80f6ca 312
f8a83ee3 313 putchar ('\n');
3b80f6ca
RH
314
315 for (i = 0; i < NUM_RTX_CODE; i++)
c5c76735
JL
316 if (! special_format (defs[i].format))
317 genmacro (i);
0313e85b
ZW
318
319 puts ("\n#endif /* GCC_GENRTL_H */");
3b80f6ca
RH
320}
321
c5c76735 322/* Generate the text of the code file we write, genrtl.c. */
0133b7d9 323
3b80f6ca 324static void
3d7aafde 325gencode (void)
3b80f6ca
RH
326{
327 const char **fmt;
328
f8a83ee3
ZW
329 puts ("#include \"config.h\"");
330 puts ("#include \"system.h\"");
4977bab6
ZW
331 puts ("#include \"coretypes.h\"");
332 puts ("#include \"tm.h\"");
f8a83ee3
ZW
333 puts ("#include \"obstack.h\"");
334 puts ("#include \"rtl.h\"");
335 puts ("#include \"ggc.h\"\n");
c5c76735
JL
336
337 for (fmt = formats; *fmt != 0; fmt++)
338 gendef (*fmt);
3b80f6ca
RH
339}
340
c5c76735
JL
341/* This is the main program. We accept only one argument, "-h", which
342 says we are writing the genrtl.h file. Otherwise we are writing the
343 genrtl.c file. */
344
3b80f6ca 345int
3d7aafde 346main (int argc, char **argv)
3b80f6ca 347{
3b80f6ca 348 find_formats ();
c5c76735 349 genlegend ();
3b80f6ca 350
c5c76735
JL
351 if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')
352 genheader ();
353 else
354 gencode ();
3b80f6ca 355
0313e85b
ZW
356 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
357 return FATAL_EXIT_CODE;
358
359 return SUCCESS_EXIT_CODE;
3b80f6ca 360}