1*e4b17023SJohn Marino /* Generate code to allocate RTL structures.
2*e4b17023SJohn Marino Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2007, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
10*e4b17023SJohn Marino version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino #include "bconfig.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino struct rtx_definition
26*e4b17023SJohn Marino {
27*e4b17023SJohn Marino const char *const enumname, *const name, *const format;
28*e4b17023SJohn Marino };
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino /* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
31*e4b17023SJohn Marino CONST_DOUBLE_FORMAT is because we're not going to be generating
32*e4b17023SJohn Marino anything for CONST_DOUBLE anyway. */
33*e4b17023SJohn Marino #define CONST_DOUBLE_FORMAT ""
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino static const struct rtx_definition defs[] =
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino #include "rtl.def" /* rtl expressions are documented here */
40*e4b17023SJohn Marino };
41*e4b17023SJohn Marino #define NUM_RTX_CODE ARRAY_SIZE(defs)
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino static const char *formats[NUM_RTX_CODE];
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino /* Decode a format letter into a C type string. */
46*e4b17023SJohn Marino
47*e4b17023SJohn Marino static const char *
type_from_format(int c)48*e4b17023SJohn Marino type_from_format (int c)
49*e4b17023SJohn Marino {
50*e4b17023SJohn Marino switch (c)
51*e4b17023SJohn Marino {
52*e4b17023SJohn Marino case 'i':
53*e4b17023SJohn Marino return "int ";
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino case 'w':
56*e4b17023SJohn Marino return "HOST_WIDE_INT ";
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino case 's':
59*e4b17023SJohn Marino return "const char *";
60*e4b17023SJohn Marino
61*e4b17023SJohn Marino case 'e': case 'u':
62*e4b17023SJohn Marino return "rtx ";
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino case 'E':
65*e4b17023SJohn Marino return "rtvec ";
66*e4b17023SJohn Marino case 't':
67*e4b17023SJohn Marino return "union tree_node *"; /* tree - typedef not available */
68*e4b17023SJohn Marino case 'B':
69*e4b17023SJohn Marino return "struct basic_block_def *"; /* basic block - typedef not available */
70*e4b17023SJohn Marino default:
71*e4b17023SJohn Marino gcc_unreachable ();
72*e4b17023SJohn Marino }
73*e4b17023SJohn Marino }
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino /* Decode a format letter into the proper accessor function. */
76*e4b17023SJohn Marino
77*e4b17023SJohn Marino static const char *
accessor_from_format(int c)78*e4b17023SJohn Marino accessor_from_format (int c)
79*e4b17023SJohn Marino {
80*e4b17023SJohn Marino switch (c)
81*e4b17023SJohn Marino {
82*e4b17023SJohn Marino case 'i':
83*e4b17023SJohn Marino return "XINT";
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino case 'w':
86*e4b17023SJohn Marino return "XWINT";
87*e4b17023SJohn Marino
88*e4b17023SJohn Marino case 's':
89*e4b17023SJohn Marino return "XSTR";
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino case 'e': case 'u':
92*e4b17023SJohn Marino return "XEXP";
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino case 'E':
95*e4b17023SJohn Marino return "XVEC";
96*e4b17023SJohn Marino
97*e4b17023SJohn Marino case 't':
98*e4b17023SJohn Marino return "XTREE";
99*e4b17023SJohn Marino
100*e4b17023SJohn Marino case 'B':
101*e4b17023SJohn Marino return "XBBDEF";
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino default:
104*e4b17023SJohn Marino gcc_unreachable ();
105*e4b17023SJohn Marino }
106*e4b17023SJohn Marino }
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino /* Return nonzero if we should ignore FMT, an RTL format, when making
109*e4b17023SJohn Marino the list of formats we write routines to create. */
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino static int
special_format(const char * fmt)112*e4b17023SJohn Marino special_format (const char *fmt)
113*e4b17023SJohn Marino {
114*e4b17023SJohn Marino return (strchr (fmt, '*') != 0
115*e4b17023SJohn Marino || strchr (fmt, 'V') != 0
116*e4b17023SJohn Marino || strchr (fmt, 'S') != 0
117*e4b17023SJohn Marino || strchr (fmt, 'n') != 0);
118*e4b17023SJohn Marino }
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino /* Return nonzero if the RTL code given by index IDX is one that we should
121*e4b17023SJohn Marino generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
122*e4b17023SJohn Marino is a wrapper in emit-rtl.c). */
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino static int
special_rtx(int idx)125*e4b17023SJohn Marino special_rtx (int idx)
126*e4b17023SJohn Marino {
127*e4b17023SJohn Marino return (strcmp (defs[idx].enumname, "CONST_INT") == 0
128*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "REG") == 0
129*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "SUBREG") == 0
130*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "MEM") == 0
131*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "PC") == 0
132*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "CC0") == 0
133*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "RETURN") == 0
134*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0
135*e4b17023SJohn Marino || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
136*e4b17023SJohn Marino }
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino /* Return nonzero if the RTL code given by index IDX is one that we should
139*e4b17023SJohn Marino generate no macro for at all (because gen_rtx_FOO is never used or
140*e4b17023SJohn Marino cannot have the obvious interface). */
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino static int
excluded_rtx(int idx)143*e4b17023SJohn Marino excluded_rtx (int idx)
144*e4b17023SJohn Marino {
145*e4b17023SJohn Marino return ((strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0)
146*e4b17023SJohn Marino || (strcmp (defs[idx].enumname, "CONST_FIXED") == 0));
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /* Place a list of all format specifiers we use into the array FORMAT. */
150*e4b17023SJohn Marino
151*e4b17023SJohn Marino static void
find_formats(void)152*e4b17023SJohn Marino find_formats (void)
153*e4b17023SJohn Marino {
154*e4b17023SJohn Marino unsigned int i;
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino for (i = 0; i < NUM_RTX_CODE; i++)
157*e4b17023SJohn Marino {
158*e4b17023SJohn Marino const char **f;
159*e4b17023SJohn Marino
160*e4b17023SJohn Marino if (special_format (defs[i].format))
161*e4b17023SJohn Marino continue;
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino for (f = formats; *f; f++)
164*e4b17023SJohn Marino if (! strcmp (*f, defs[i].format))
165*e4b17023SJohn Marino break;
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino if (*f == 0)
168*e4b17023SJohn Marino *f = defs[i].format;
169*e4b17023SJohn Marino }
170*e4b17023SJohn Marino }
171*e4b17023SJohn Marino
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino /* Generate macros to generate RTL of code IDX using the functions we
174*e4b17023SJohn Marino write. */
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino static void
genmacro(int idx)177*e4b17023SJohn Marino genmacro (int idx)
178*e4b17023SJohn Marino {
179*e4b17023SJohn Marino const char *p;
180*e4b17023SJohn Marino int i;
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
183*e4b17023SJohn Marino gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino if (excluded_rtx (idx))
186*e4b17023SJohn Marino /* Don't define a macro for this code. */
187*e4b17023SJohn Marino return;
188*e4b17023SJohn Marino
189*e4b17023SJohn Marino printf ("#define gen_rtx_%s%s(MODE",
190*e4b17023SJohn Marino special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino for (p = defs[idx].format, i = 0; *p != 0; p++)
193*e4b17023SJohn Marino if (*p != '0')
194*e4b17023SJohn Marino printf (", ARG%d", i++);
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino printf (") \\\n gen_rtx_fmt_%s (%s, (MODE)",
197*e4b17023SJohn Marino defs[idx].format, defs[idx].enumname);
198*e4b17023SJohn Marino
199*e4b17023SJohn Marino for (p = defs[idx].format, i = 0; *p != 0; p++)
200*e4b17023SJohn Marino if (*p != '0')
201*e4b17023SJohn Marino printf (", (ARG%d)", i++);
202*e4b17023SJohn Marino
203*e4b17023SJohn Marino puts (")");
204*e4b17023SJohn Marino }
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino /* Generate the code for the function to generate RTL whose
207*e4b17023SJohn Marino format is FORMAT. */
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino static void
gendef(const char * format)210*e4b17023SJohn Marino gendef (const char *format)
211*e4b17023SJohn Marino {
212*e4b17023SJohn Marino const char *p;
213*e4b17023SJohn Marino int i, j;
214*e4b17023SJohn Marino
215*e4b17023SJohn Marino /* Start by writing the definition of the function name and the types
216*e4b17023SJohn Marino of the arguments. */
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino printf ("static inline rtx\ngen_rtx_fmt_%s_stat (RTX_CODE code, enum machine_mode mode", format);
219*e4b17023SJohn Marino for (p = format, i = 0; *p != 0; p++)
220*e4b17023SJohn Marino if (*p != '0')
221*e4b17023SJohn Marino printf (",\n\t%sarg%d", type_from_format (*p), i++);
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino puts (" MEM_STAT_DECL)");
224*e4b17023SJohn Marino
225*e4b17023SJohn Marino /* Now write out the body of the function itself, which allocates
226*e4b17023SJohn Marino the memory and initializes it. */
227*e4b17023SJohn Marino puts ("{");
228*e4b17023SJohn Marino puts (" rtx rt;");
229*e4b17023SJohn Marino puts (" rt = rtx_alloc_stat (code PASS_MEM_STAT);\n");
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino puts (" PUT_MODE (rt, mode);");
232*e4b17023SJohn Marino
233*e4b17023SJohn Marino for (p = format, i = j = 0; *p ; ++p, ++i)
234*e4b17023SJohn Marino if (*p != '0')
235*e4b17023SJohn Marino printf (" %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
236*e4b17023SJohn Marino else
237*e4b17023SJohn Marino printf (" X0EXP (rt, %d) = NULL_RTX;\n", i);
238*e4b17023SJohn Marino
239*e4b17023SJohn Marino puts ("\n return rt;\n}\n");
240*e4b17023SJohn Marino printf ("#define gen_rtx_fmt_%s(c, m", format);
241*e4b17023SJohn Marino for (p = format, i = 0; *p != 0; p++)
242*e4b17023SJohn Marino if (*p != '0')
243*e4b17023SJohn Marino printf (", p%i",i++);
244*e4b17023SJohn Marino printf (")\\\n gen_rtx_fmt_%s_stat (c, m", format);
245*e4b17023SJohn Marino for (p = format, i = 0; *p != 0; p++)
246*e4b17023SJohn Marino if (*p != '0')
247*e4b17023SJohn Marino printf (", p%i",i++);
248*e4b17023SJohn Marino printf (" MEM_STAT_INFO)\n\n");
249*e4b17023SJohn Marino }
250*e4b17023SJohn Marino
251*e4b17023SJohn Marino /* Generate the documentation header for files we write. */
252*e4b17023SJohn Marino
253*e4b17023SJohn Marino static void
genlegend(void)254*e4b17023SJohn Marino genlegend (void)
255*e4b17023SJohn Marino {
256*e4b17023SJohn Marino puts ("/* Generated automatically by gengenrtl from rtl.def. */\n");
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino /* Generate the text of the header file we make, genrtl.h. */
260*e4b17023SJohn Marino
261*e4b17023SJohn Marino static void
genheader(void)262*e4b17023SJohn Marino genheader (void)
263*e4b17023SJohn Marino {
264*e4b17023SJohn Marino unsigned int i;
265*e4b17023SJohn Marino const char **fmt;
266*e4b17023SJohn Marino
267*e4b17023SJohn Marino puts ("#ifndef GCC_GENRTL_H");
268*e4b17023SJohn Marino puts ("#define GCC_GENRTL_H\n");
269*e4b17023SJohn Marino puts ("#include \"statistics.h\"\n");
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino for (fmt = formats; *fmt; ++fmt)
272*e4b17023SJohn Marino gendef (*fmt);
273*e4b17023SJohn Marino
274*e4b17023SJohn Marino putchar ('\n');
275*e4b17023SJohn Marino
276*e4b17023SJohn Marino for (i = 0; i < NUM_RTX_CODE; i++)
277*e4b17023SJohn Marino if (! special_format (defs[i].format))
278*e4b17023SJohn Marino genmacro (i);
279*e4b17023SJohn Marino
280*e4b17023SJohn Marino puts ("\n#endif /* GCC_GENRTL_H */");
281*e4b17023SJohn Marino }
282*e4b17023SJohn Marino
283*e4b17023SJohn Marino /* This is the main program. */
284*e4b17023SJohn Marino
285*e4b17023SJohn Marino int
main(void)286*e4b17023SJohn Marino main (void)
287*e4b17023SJohn Marino {
288*e4b17023SJohn Marino find_formats ();
289*e4b17023SJohn Marino genlegend ();
290*e4b17023SJohn Marino
291*e4b17023SJohn Marino genheader ();
292*e4b17023SJohn Marino
293*e4b17023SJohn Marino if (ferror (stdout) || fflush (stdout) || fclose (stdout))
294*e4b17023SJohn Marino return FATAL_EXIT_CODE;
295*e4b17023SJohn Marino
296*e4b17023SJohn Marino return SUCCESS_EXIT_CODE;
297*e4b17023SJohn Marino }
298