现在的位置: 首页 > 综合 > 正文

GCC后端及汇编发布(46)

2012年03月15日 ⁄ 综合 ⁄ 共 7378字 ⁄ 字号 评论关闭

16.   gengenrtl工具

16.1.  概览

这个工具从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  }

16.2.  输出genrtl.h

除了由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_formatgendecl产生这个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  }

16.3.  输出genrtl.c

构建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  }

抱歉!评论已关闭.