xref: /dflybsd-src/contrib/gcc-4.7/gcc/gengenrtl.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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