GCC's bacl-end & assemble emission (43)

13.   Toolof genconfig

The tool will generate constants such as “largest operand number seen”, “largest number ofmatch_dup in any instruction”, “maximum number of insns seen in a split” etc.teogther with macros defined to indicate the presence of special instructions,such as HAVE_conditional_move,HAVE_peephole2,into file insn-config.h

 

260  int

261  main (int argc, char **argv)                                                                 ingenconfig.c

262  {

263   rtx desc;

264 

265   progname= "genconfig";

266 

267   if (argc <= 1)

268     fatal ("no input file name");

269 

270   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)

271     return (FATAL_EXIT_CODE);

272 

273   puts ("/* Generated automatically by the program`genconfig'");

274   puts ("   from the machinedescription file `md'.  */\n");

275   puts ("#ifndef GCC_INSN_CONFIG_H");

276   puts ("#define GCC_INSN_CONFIG_H\n");

277 

278   /* Allow at least 30 operands for the sake ofasm constructs.  */

279    /* ??? We *really* ought to reorganize thingssuch that there

280      is no fixed upper bound.  */

281   max_recog_operands= 29;  /* Wewill add 1 later.  */

282   max_dup_operands= 1;

283 

284   /* Read the machine description.  */

285 

286   while (1)

287   {

288     int line_no, insn_code_number = 0;

289 

290     desc = read_md_rtx (&line_no,&insn_code_number);

291     if (desc == NULL)

292       break;

293        

294     switch (GET_CODE (desc))

295     {

296       case DEFINE_INSN:

297         gen_insn (desc);

298         break;

299          

300       case DEFINE_EXPAND:

301         gen_expand (desc);

302         break;

303 

304       case DEFINE_SPLIT:

305         gen_split (desc);

306         break;

307 

308       case DEFINE_PEEPHOLE2:

309         have_peephole2_flag= 1;

310         gen_peephole2 (desc);

311         break;

312 

313       case DEFINE_PEEPHOLE:

314         have_peephole_flag= 1;

315         gen_peephole (desc);

316         break;

317 

318       default:

319         break;

320     }

321   }

322 

323   printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands+ 1);

324   printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);

325 

326   /* This is conditionally defined, in case theuser writes code which emits

327      more splits than we can readily see (andknows s/he does it).  */

328   printf ("#ifndef MAX_INSNS_PER_SPLIT\n");

329   printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);

330   printf ("#endif\n");

331 

332   if (have_cc0_flag)

333   {

334     printf ("#define HAVE_cc0 1\n");

335     printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");

336   }

337   else

338   {

339     printf ("#define CC0_P(X) 0\n");

340   }

341 

342   if (have_cmove_flag)

343     printf ("#define HAVE_conditional_move 1\n");

344 

345   if (have_cond_exec_flag)

346     printf ("#define HAVE_conditional_execution 1\n");

347 

348   if (have_lo_sum_flag)

349     printf ("#define HAVE_lo_sum 1\n");

350 

351   if (have_peephole_flag)

352     printf ("#define HAVE_peephole 1\n");

353 

354   if (have_peephole2_flag)

355   {

356     printf ("#define HAVE_peephole2 1\n");

357     printf ("#defineMAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2);

358   }

359 

360   puts("\n#endif /* GCC_INSN_CONFIG_H */");

361 

362   if (ferror (stdout) || fflush (stdout) || fclose (stdout))

363     return FATAL_EXIT_CODE;

364 

365   return SUCCESS_EXIT_CODE;

366  }

 

Just takes gen_insn as example, for other patterns, thehandling functions are similar.

 

170  static void

171  gen_insn (rtx insn)                                                                              in genconfig.c

172  {

173   int i;

174 

175   /* Walk the insn pattern to gather the#define's status.  */

176   clobbers_seen_this_insn= 0;

177   dup_operands_seen_this_insn= 0;

178    if (XVEC (insn, 1) != 0)

179      for(i = 0; i < XVECLEN (insn, 1); i++)

180       walk_insn_part (XVECEXP (insn, 1, i), 1,0);

181 

182   if (clobbers_seen_this_insn> max_clobbers_per_insn)

183     max_clobbers_per_insn= clobbers_seen_this_insn;

184   if (dup_operands_seen_this_insn> max_dup_operands)

185     max_dup_operands= dup_operands_seen_this_insn;

186  }

 

We have seen that the second child of define_insn pattern is the RTLtemplate which is a vector of incomplete RTL expressions which show what theinstruction should look like. It is incomplete because it may contain`match_operand', `match_operator', and `match_dup' expressions that stand foroperands of the instruction. walk_insn_part is invoked for every item in thevector.

 

66    static void

67    walk_insn_part (rtx part, int recog_p, int non_pc_set_src)                       in genconfig.c

68    {

69      int i, j;

70      RTX_CODE code;

71     const char *format_ptr;

72   

73     if (part == 0)

74       return;

75   

76     code = GET_CODE (part);

77     switch (code)

78     {

79       case CLOBBER:

80         clobbers_seen_this_insn++;

81         break;

82   

83       case MATCH_OPERAND:

84         if (XINT (part, 0) > max_recog_operands)

85            max_recog_operands = XINT (part, 0);

86         return;

87   

88       case MATCH_OP_DUP:

89       case MATCH_PAR_DUP:

90         ++dup_operands_seen_this_insn;

91       case MATCH_SCRATCH:

92       case MATCH_PARALLEL:

93       case MATCH_OPERATOR:

94         if (XINT (part, 0) > max_recog_operands)

95            max_recog_operands = XINT (part, 0);

96         /* Now scan the rtl's in the vector inside theMATCH_OPERATOR or

97            MATCH_PARALLEL.  */

98         break;

99   

100     case LABEL_REF:

101       if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)

102         break;

103       return;

104 

105     case MATCH_DUP:

106       ++dup_operands_seen_this_insn;

107       if (XINT (part, 0) > max_recog_operands)

108         max_recog_operands= XINT (part, 0);

109       return;

110 

111     case CC0:

112       if (recog_p)

113         have_cc0_flag= 1;

114       return;

115 

116     case LO_SUM:

117       if (recog_p)

118         have_lo_sum_flag= 1;

119       return;

120 

121     case SET:

122       walk_insn_part (SET_DEST (part), 0,recog_p);

123       walk_insn_part (SET_SRC (part), recog_p,

124                     GET_CODE (SET_DEST (part))!= PC);

125       return;

126 

127     case IF_THEN_ELSE:

128       /* Only consider this machine as having aconditional move if the

129          two arms of the IF_THEN_ELSE are bothMATCH_OPERAND. Otherwise,

130          we have some specific IF_THEN_ELSEconstruct (like the doz

131          instruction on the RS/6000) that can'tbe used in the general

132          context we want it for.  */

133 

134       if (recog_p && non_pc_set_src

135          && GET_CODE (XEXP (part, 1)) ==MATCH_OPERAND

136          && GET_CODE (XEXP (part, 2)) ==MATCH_OPERAND)

137         have_cmove_flag= 1;

138       break;

139 

140     case COND_EXEC:

141       if (recog_p)

142         have_cond_exec_flag= 1;

143       break;

144 

145     case REG: caseCONST_INT: case SYMBOL_REF:

146     case PC:

147       return;

148 

149     default:

150       break;

151   }

152 

153   format_ptr = GET_RTX_FORMAT (GET_CODE (part));

154 

155   for (i = 0; i < GET_RTX_LENGTH(GET_CODE (part)); i++)

156     switch (*format_ptr++)

157     {

158       case 'e':

159       case 'u':

160         walk_insn_part (XEXP(part, i), recog_p, non_pc_set_src);

161         break;

162       case 'E':

163         if (XVEC (part, i) != NULL)

164            for(j = 0; j < XVECLEN (part, i); j++)

165              walk_insn_part(XVECEXP (part, i, j), recog_p, non_pc_set_src);

166         break;

167     }

168  }

 

Parameter recog_p will be nonzero if the pattern is seen ina context where it will be used to recognize, rather than just generate aninstruction. And parameter non_pc_set_src will be nonzero if this pattern isseen in a SET_SRC of a SET whose destination is not (pc).

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭