这个工具从rtl.def产生genrtl.h及genrtl.c。这些输出的文件给出了根据在rtl.def文件中的定义产生各种rtl对象的函数。
340 int
341 main (int argc, char **argv) ingengenrtl.c
342 {
343 find_formats ();
344 genlegend ();
345
346 if (argc == 2 && argv[1][0]== '-' && argv[1][1] == 'h')
347 genheader ();
348 else
349 gencode ();
350
351 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
352 return FATAL_EXIT_CODE;
353
354 return SUCCESS_EXIT_CODE;
355 }
至于rtx的格式,其细节如下:
Ø “*”未定义,可以导致一个警告消息
Ø “0”域未使用(或以一个依赖阶段的方式使用)不输出任何东西
Ø “i”一个整数,输出这个整数
Ø “n”类似“i”,但从note_insn_name输出项
Ø “w”一个宽度为HOST_BITS_PER_WIDE_INT的整数,输出这个整数
Ø “s”一个字符串指针,输出这个字符串
Ø “S”类似“s”,但是可选:所包含的rtx可能在这个操作数之前结束
Ø “T”类似“s”,但为RTL阅读器特殊处理;仅出现在机器描述模式中。
Ø “e”一个指向rtl表达式的指针,输出这个表达式
Ø “E”一个指向若干rtl表达式的指针,输出这个rtl表达式列表
Ø “V”类似“E”,但可选:所包含的rtx可能在这个操作数之前结束
Ø “u”一个指向其它指令的指针,输出这个指令的uid。
Ø “b”一个指向位图头的指针
Ø “B”是一个基本块的指针。
Ø “t”是一个树指针。
165 static void
166 find_formats (void) ingengenrtl.c
167 {
168 unsigned int i;
169
170 for(i = 0; i < NUM_RTX_CODE; i++)
171 {
172 const char **f;
173
174 if (special_format (defs[i].format))
175 continue;
176
177 for(f = formats;*f; f++)
178 if (! strcmp (*f, defs[i].format))
179 break;
180
181 if (*f == 0)
182 *f = defs[i].format;
183 }
184 }
在174行的defs定义如下。它从rtl.def扩展而来。
36 #defineDEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
37
38 static const structrtx_definition defs[] =
39 {
40 #include "rtl.def" /* rtlexpressions are documented here */
41 };
26 struct rtx_definition
27 {
28 const char *constenumname, *const name, *const format;
29 };
130 static int
131 special_format (const char *fmt) ingengenrtl.c
132 {
133 return (strchr (fmt, '*') != 0
134 || strchr (fmt, 'V') != 0
135 || strchr (fmt, 'S') != 0
136 || strchr (fmt, 'n') != 0);
137 }
除了由special_format滤掉的格式,格式将被保存入format。genrtl.h由genheader生成。
296 static void
297 genheader (void) ingengenrtl.c
298 {
299 unsigned int i;
300 const char **fmt;
301
302 puts ("#ifndef GCC_GENRTL_H");
303 puts ("#define GCC_GENRTL_H\n");
304
305 for(fmt = formats;*fmt; ++fmt)
306 gendecl (*fmt);
307
308 putchar ('\n');
309
310 for(i = 0; i < NUM_RTX_CODE; i++)
311 if (! special_format (defs[i].format))
312 genmacro (i);
313
314 puts ("\n#endif /* GCC_GENRTL_H */");
315 }
注意在上面306行,格式必须通过special_format。gendecl产生这个rtx生成函数的声明。
188 static void
189 gendecl (const char *format) ingengenrtl.c
190 {
191 const char *p;
192 int i, pos;
193
194 printf ("externrtx gen_rtx_fmt_%s\t (RTX_CODE, ", format);
195 printf ("enum machine_modemode");
196
197 /* Write each parameter that is needed andstart a new line when the line
198 would overflow. */
199 for (p = format, i = 0, pos = 75; *p !=0; p++)
200 if (*p != '0')
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
212 printf (");\n");
213 }
type_from_format把rtx格式映射到相应的c类型。
61 static const char *
62 type_from_format (int c) ingengenrtl.c
63 {
64 switch (c)
65 {
66 case 'i':
67 return "int ";
68
69 case 'w':
70 return "HOST_WIDE_INT ";
71
72 case 's':
73 return "const char *";
74
75 case 'e': case 'u':
76 return "rtx ";
77
78 case 'E':
79 return "rtvec ";
80 case 'b':
81 return "struct bitmap_head_def*"; /*bitmap - typedef not available */
82 case 't':
83 return "union tree_node*"; /*tree - typedef not available */
84 case 'B':
85 return "struct basic_block_def*"; /*basic block - typedef not available */
86 default:
87 abort ();
88 }
89 }
至于DEF_RTL_EXPR的定义,ENUM将被输出作rtx_code,而在编译期间构建rtx对象的大部分时间,rtx_code将为所构建的对象指定。因此genmacro将为要构建的rtx对象,根据rtx_code,输出宏。
218 static void
219 genmacro (int idx) ingengenrtl.c
220 {
221 const char *p;
222 int i;
223
224 /* We write a macro that definesgen_rtx_RTLCODE to be an equivalent to
225 gen_rtx_fmt_FORMAT where FORMAT is theRTX_FORMAT of RTLCODE. */
226
227 if (excluded_rtx (idx))
228 /* Don't define a macro for this code. */
229 return;
230
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++)
235 if (*p != '0')
236 printf (", ARG%d", i++);
237
238 printf (") \\\n gen_rtx_fmt_%s (%s, (MODE)",
239 defs[idx].format, defs[idx].enumname);
240
241 for(p = defs[idx].format,i = 0; *p != 0; p++)
242 if (*p != '0')
243 printf (", (ARG%d)", i++);
244
245 puts (")");
246 }
special_rtx的细节如下。
143 static int
144 special_rtx (int idx) ingengenrtl.c
145 {
146 return (strcmp (defs[idx].enumname,"CONST_INT") == 0
147 || strcmp (defs[idx].enumname,"REG") == 0
148 || strcmp (defs[idx].enumname,"SUBREG") == 0
149 || strcmp (defs[idx].enumname,"MEM") == 0
150 || strcmp (defs[idx].enumname,"CONST_VECTOR") == 0);
151 }
构建rtx对象的函数的定义由gencode生成。
319 static void
320 gencode (void) ingengenrtl.c
321 {
322 const char **fmt;
323
324 puts ("#include \"config.h\"");
325 puts ("#include \"system.h\"");
326 puts ("#include \"coretypes.h\"");
327 puts ("#include \"tm.h\"");
328 puts ("#include \"obstack.h\"");
329 puts ("#include \"rtl.h\"");
330 puts ("#include \"ggc.h\"\n");
331
332 for(fmt = formats;*fmt != 0; fmt++)
333 gendef (*fmt);
334 }
仅对于普通的格式对象,将定义构建函数。
251 static void
252 gendef (const char *format) in gengenrtl.c
253 {
254 const char *p;
255 int i, j;
256
257 /* Start by writing the definition of thefunction name and the types
258 of thearguments. */
259
260 printf ("rtx\ngen_rtx_fmt_%s(RTX_CODE code, enum machine_mode mode", format);
261 for(p = format, i = 0; *p != 0; p++)
262 if (*p != '0')
263 printf (",\n\t%sarg%d", type_from_format(*p), i++);
264
265 puts (")");
266
267 /* Now write out the body of the functionitself, which allocates
268 the memory and initializes it. */
269 puts ("{");
270 puts (" rtx rt;");
271 puts (" rt = ggc_alloc_rtx(code);\n");
272
273 puts (" memset (rt, 0,RTX_HDR_SIZE);\n");
274 puts (" PUT_CODE (rt, code);");
275 puts (" PUT_MODE (rt, mode);");
276
277 for(p = format, i = j = 0; *p ; ++p, ++i)
278 if (*p != '0')
279 printf (" %s (rt, %d) =arg%d;\n", accessor_from_format (*p),i, j++);
280 else
281 printf (" X0EXP (rt, %d) =NULL_RTX;\n", i);
282
283 puts ("\n returnrt;\n}\n");
284 }
accessor_from_format把格式映射到访问它们的rtx宏。
93 static const char *
94 accessor_from_format (int c) in gengenrtl.c
95 {
96 switch (c)
97 {
98 case 'i':
99 return "XINT";
100
101 case 'w':
102 return "XWINT";
103
104 case 's':
105 return "XSTR";
106
107 case 'e': case 'u':
108 return "XEXP";
109
110 case 'E':
111 return "XVEC";
112
113 case 'b':
114 return "XBITMAP";
115
116 case 't':
117 return "XTREE";
118
119 case 'B':
120 return "XBBDEF";
121
122 default:
123 abort ();
124 }
125 }