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