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