]>
Commit | Line | Data |
---|---|---|
caef9864 | 1 | /* Generate from machine description: |
caef9864 | 2 | - some #define configuration flags. |
d353bf18 | 3 | Copyright (C) 1987-2015 Free Software Foundation, Inc. |
caef9864 | 4 | |
f12b58b3 | 5 | This file is part of GCC. |
caef9864 | 6 | |
f12b58b3 | 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 | |
8c4c00c1 | 9 | Software Foundation; either version 3, or (at your option) any later |
f12b58b3 | 10 | version. |
caef9864 | 11 | |
f12b58b3 | 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. | |
caef9864 | 16 | |
17 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
caef9864 | 20 | |
21 | ||
805e22b2 | 22 | #include "bconfig.h" |
5ce88198 | 23 | #include "system.h" |
805e22b2 | 24 | #include "coretypes.h" |
25 | #include "tm.h" | |
caef9864 | 26 | #include "rtl.h" |
04b58880 | 27 | #include "errors.h" |
c5ddd6b5 | 28 | #include "gensupport.h" |
caef9864 | 29 | |
caef9864 | 30 | |
caef9864 | 31 | /* flags to determine output of machine description dependent #define's. */ |
f087bd1f | 32 | static int max_recog_operands; /* Largest operand number seen. */ |
33 | static int max_dup_operands; /* Largest number of match_dup in any insn. */ | |
caef9864 | 34 | static int max_clobbers_per_insn; |
caef9864 | 35 | static int have_cc0_flag; |
d93fe581 | 36 | static int have_cmove_flag; |
406034fa | 37 | static int have_cond_exec_flag; |
caef9864 | 38 | static int have_lo_sum_flag; |
9da3143a | 39 | static int have_rotate_flag; |
40 | static int have_rotatert_flag; | |
82575fa7 | 41 | static int have_peephole_flag; |
42 | static int have_peephole2_flag; | |
caef9864 | 43 | |
44 | /* Maximum number of insns seen in a split. */ | |
45 | static int max_insns_per_split = 1; | |
46 | ||
3e9f1237 | 47 | /* Maximum number of input insns for peephole2. */ |
48 | static int max_insns_per_peep2; | |
49 | ||
caef9864 | 50 | static int clobbers_seen_this_insn; |
51 | static int dup_operands_seen_this_insn; | |
52 | ||
1a97be37 | 53 | static void walk_insn_part (rtx, int, int); |
12693c81 | 54 | |
6ef828f9 | 55 | /* RECOG_P will be nonzero if this pattern was seen in a context where it will |
48e1416a | 56 | be used to recognize, rather than just generate an insn. |
d93fe581 | 57 | |
6ef828f9 | 58 | NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC |
d93fe581 | 59 | of a SET whose destination is not (pc). */ |
caef9864 | 60 | |
61 | static void | |
1a97be37 | 62 | walk_insn_part (rtx part, int recog_p, int non_pc_set_src) |
caef9864 | 63 | { |
19cb6b50 | 64 | int i, j; |
65 | RTX_CODE code; | |
66 | const char *format_ptr; | |
caef9864 | 67 | |
68 | if (part == 0) | |
69 | return; | |
70 | ||
71 | code = GET_CODE (part); | |
72 | switch (code) | |
73 | { | |
74 | case CLOBBER: | |
75 | clobbers_seen_this_insn++; | |
76 | break; | |
77 | ||
78 | case MATCH_OPERAND: | |
79 | if (XINT (part, 0) > max_recog_operands) | |
80 | max_recog_operands = XINT (part, 0); | |
caef9864 | 81 | return; |
82 | ||
83 | case MATCH_OP_DUP: | |
0262156a | 84 | case MATCH_PAR_DUP: |
caef9864 | 85 | ++dup_operands_seen_this_insn; |
86 | case MATCH_SCRATCH: | |
87 | case MATCH_PARALLEL: | |
88 | case MATCH_OPERATOR: | |
89 | if (XINT (part, 0) > max_recog_operands) | |
90 | max_recog_operands = XINT (part, 0); | |
91 | /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or | |
92 | MATCH_PARALLEL. */ | |
93 | break; | |
94 | ||
95 | case LABEL_REF: | |
b49f2e4b | 96 | if (GET_CODE (LABEL_REF_LABEL (part)) == MATCH_OPERAND |
97 | || GET_CODE (LABEL_REF_LABEL (part)) == MATCH_DUP) | |
caef9864 | 98 | break; |
99 | return; | |
100 | ||
101 | case MATCH_DUP: | |
102 | ++dup_operands_seen_this_insn; | |
103 | if (XINT (part, 0) > max_recog_operands) | |
104 | max_recog_operands = XINT (part, 0); | |
105 | return; | |
106 | ||
107 | case CC0: | |
108 | if (recog_p) | |
109 | have_cc0_flag = 1; | |
110 | return; | |
111 | ||
112 | case LO_SUM: | |
113 | if (recog_p) | |
114 | have_lo_sum_flag = 1; | |
115 | return; | |
116 | ||
9da3143a | 117 | case ROTATE: |
118 | if (recog_p) | |
119 | have_rotate_flag = 1; | |
120 | return; | |
121 | ||
122 | case ROTATERT: | |
123 | if (recog_p) | |
124 | have_rotatert_flag = 1; | |
125 | return; | |
126 | ||
d93fe581 | 127 | case SET: |
128 | walk_insn_part (SET_DEST (part), 0, recog_p); | |
129 | walk_insn_part (SET_SRC (part), recog_p, | |
130 | GET_CODE (SET_DEST (part)) != PC); | |
131 | return; | |
132 | ||
133 | case IF_THEN_ELSE: | |
517ef109 | 134 | /* Only consider this machine as having a conditional move if the |
135 | two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, | |
136 | we have some specific IF_THEN_ELSE construct (like the doz | |
137 | instruction on the RS/6000) that can't be used in the general | |
406034fa | 138 | context we want it for. */ |
517ef109 | 139 | |
140 | if (recog_p && non_pc_set_src | |
141 | && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND | |
142 | && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) | |
d93fe581 | 143 | have_cmove_flag = 1; |
406034fa | 144 | break; |
145 | ||
146 | case COND_EXEC: | |
147 | if (recog_p) | |
148 | have_cond_exec_flag = 1; | |
d93fe581 | 149 | break; |
150 | ||
caef9864 | 151 | case REG: case CONST_INT: case SYMBOL_REF: |
152 | case PC: | |
153 | return; | |
3ef9782d | 154 | |
155 | default: | |
156 | break; | |
caef9864 | 157 | } |
158 | ||
159 | format_ptr = GET_RTX_FORMAT (GET_CODE (part)); | |
160 | ||
161 | for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) | |
162 | switch (*format_ptr++) | |
163 | { | |
164 | case 'e': | |
165 | case 'u': | |
d93fe581 | 166 | walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); |
caef9864 | 167 | break; |
168 | case 'E': | |
169 | if (XVEC (part, i) != NULL) | |
170 | for (j = 0; j < XVECLEN (part, i); j++) | |
d93fe581 | 171 | walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); |
caef9864 | 172 | break; |
173 | } | |
174 | } | |
175 | ||
176 | static void | |
c04601c1 | 177 | gen_insn (md_rtx_info *info) |
caef9864 | 178 | { |
179 | int i; | |
180 | ||
181 | /* Walk the insn pattern to gather the #define's status. */ | |
c04601c1 | 182 | rtx insn = info->def; |
caef9864 | 183 | clobbers_seen_this_insn = 0; |
184 | dup_operands_seen_this_insn = 0; | |
185 | if (XVEC (insn, 1) != 0) | |
186 | for (i = 0; i < XVECLEN (insn, 1); i++) | |
d93fe581 | 187 | walk_insn_part (XVECEXP (insn, 1, i), 1, 0); |
caef9864 | 188 | |
189 | if (clobbers_seen_this_insn > max_clobbers_per_insn) | |
190 | max_clobbers_per_insn = clobbers_seen_this_insn; | |
191 | if (dup_operands_seen_this_insn > max_dup_operands) | |
192 | max_dup_operands = dup_operands_seen_this_insn; | |
193 | } | |
194 | ||
195 | /* Similar but scan a define_expand. */ | |
196 | ||
197 | static void | |
c04601c1 | 198 | gen_expand (md_rtx_info *info) |
caef9864 | 199 | { |
200 | int i; | |
201 | ||
202 | /* Walk the insn pattern to gather the #define's status. */ | |
203 | ||
204 | /* Note that we don't bother recording the number of MATCH_DUPs | |
205 | that occur in a gen_expand, because only reload cares about that. */ | |
c04601c1 | 206 | rtx insn = info->def; |
caef9864 | 207 | if (XVEC (insn, 1) != 0) |
208 | for (i = 0; i < XVECLEN (insn, 1); i++) | |
209 | { | |
210 | /* Compute the maximum SETs and CLOBBERS | |
211 | in any one of the sub-insns; | |
212 | don't sum across all of them. */ | |
213 | clobbers_seen_this_insn = 0; | |
214 | ||
d93fe581 | 215 | walk_insn_part (XVECEXP (insn, 1, i), 0, 0); |
caef9864 | 216 | |
217 | if (clobbers_seen_this_insn > max_clobbers_per_insn) | |
218 | max_clobbers_per_insn = clobbers_seen_this_insn; | |
219 | } | |
220 | } | |
221 | ||
222 | /* Similar but scan a define_split. */ | |
223 | ||
224 | static void | |
c04601c1 | 225 | gen_split (md_rtx_info *info) |
caef9864 | 226 | { |
227 | int i; | |
228 | ||
229 | /* Look through the patterns that are matched | |
230 | to compute the maximum operand number. */ | |
c04601c1 | 231 | rtx split = info->def; |
caef9864 | 232 | for (i = 0; i < XVECLEN (split, 0); i++) |
d93fe581 | 233 | walk_insn_part (XVECEXP (split, 0, i), 1, 0); |
caef9864 | 234 | /* Look at the number of insns this insn could split into. */ |
235 | if (XVECLEN (split, 2) > max_insns_per_split) | |
236 | max_insns_per_split = XVECLEN (split, 2); | |
237 | } | |
238 | ||
239 | static void | |
c04601c1 | 240 | gen_peephole (md_rtx_info *info) |
caef9864 | 241 | { |
242 | int i; | |
243 | ||
244 | /* Look through the patterns that are matched | |
245 | to compute the maximum operand number. */ | |
c04601c1 | 246 | rtx peep = info->def; |
caef9864 | 247 | for (i = 0; i < XVECLEN (peep, 0); i++) |
d93fe581 | 248 | walk_insn_part (XVECEXP (peep, 0, i), 1, 0); |
caef9864 | 249 | } |
caef9864 | 250 | |
3e9f1237 | 251 | static void |
c04601c1 | 252 | gen_peephole2 (md_rtx_info *info) |
3e9f1237 | 253 | { |
254 | int i, n; | |
255 | ||
256 | /* Look through the patterns that are matched | |
257 | to compute the maximum operand number. */ | |
c04601c1 | 258 | rtx peep = info->def; |
3e9f1237 | 259 | for (i = XVECLEN (peep, 0) - 1; i >= 0; --i) |
260 | walk_insn_part (XVECEXP (peep, 0, i), 1, 0); | |
261 | ||
262 | /* Look at the number of insns this insn can be matched from. */ | |
263 | for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i) | |
264 | if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP | |
265 | && GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH) | |
266 | n++; | |
267 | if (n > max_insns_per_peep2) | |
268 | max_insns_per_peep2 = n; | |
269 | } | |
270 | ||
caef9864 | 271 | int |
1a97be37 | 272 | main (int argc, char **argv) |
caef9864 | 273 | { |
04b58880 | 274 | progname = "genconfig"; |
caef9864 | 275 | |
77ba95d0 | 276 | if (!init_rtx_reader_args (argc, argv)) |
c5ddd6b5 | 277 | return (FATAL_EXIT_CODE); |
caef9864 | 278 | |
d0c809e1 | 279 | puts ("/* Generated automatically by the program `genconfig'"); |
280 | puts (" from the machine description file `md'. */\n"); | |
281 | puts ("#ifndef GCC_INSN_CONFIG_H"); | |
282 | puts ("#define GCC_INSN_CONFIG_H\n"); | |
caef9864 | 283 | |
2c7f203c | 284 | /* Allow at least 30 operands for the sake of asm constructs. */ |
285 | /* ??? We *really* ought to reorganize things such that there | |
286 | is no fixed upper bound. */ | |
287 | max_recog_operands = 29; /* We will add 1 later. */ | |
caef9864 | 288 | max_dup_operands = 1; |
289 | ||
290 | /* Read the machine description. */ | |
291 | ||
c04601c1 | 292 | md_rtx_info info; |
293 | while (read_md_rtx (&info)) | |
294 | switch (GET_CODE (info.def)) | |
295 | { | |
296 | case DEFINE_INSN: | |
297 | gen_insn (&info); | |
298 | break; | |
c5ddd6b5 | 299 | |
c04601c1 | 300 | case DEFINE_EXPAND: |
301 | gen_expand (&info); | |
caef9864 | 302 | break; |
48e1416a | 303 | |
c04601c1 | 304 | case DEFINE_SPLIT: |
305 | gen_split (&info); | |
306 | break; | |
307 | ||
308 | case DEFINE_PEEPHOLE2: | |
309 | have_peephole2_flag = 1; | |
310 | gen_peephole2 (&info); | |
311 | break; | |
312 | ||
313 | case DEFINE_PEEPHOLE: | |
314 | have_peephole_flag = 1; | |
315 | gen_peephole (&info); | |
316 | break; | |
317 | ||
318 | default: | |
319 | break; | |
320 | } | |
caef9864 | 321 | |
3e9f1237 | 322 | printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1); |
323 | printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands); | |
caef9864 | 324 | |
325 | /* This is conditionally defined, in case the user writes code which emits | |
326 | more splits than we can readily see (and knows s/he does it). */ | |
406034fa | 327 | printf ("#ifndef MAX_INSNS_PER_SPLIT\n"); |
328 | printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split); | |
329 | printf ("#endif\n"); | |
caef9864 | 330 | |
caef9864 | 331 | if (have_cc0_flag) |
c4bb5f73 | 332 | { |
333 | printf ("#define HAVE_cc0 1\n"); | |
334 | printf ("#define CC0_P(X) ((X) == cc0_rtx)\n"); | |
335 | } | |
336 | else | |
337 | { | |
f57ff396 | 338 | /* We output CC0_P this way to make sure that X is declared |
339 | somewhere. */ | |
27a6f97d | 340 | printf ("#define HAVE_cc0 0\n"); |
f57ff396 | 341 | printf ("#define CC0_P(X) ((X) ? 0 : 0)\n"); |
c4bb5f73 | 342 | } |
caef9864 | 343 | |
d93fe581 | 344 | if (have_cmove_flag) |
eb1c92fb | 345 | printf ("#define HAVE_conditional_move 1\n"); |
cf2f2c56 | 346 | else |
347 | printf ("#define HAVE_conditional_move 0\n"); | |
d93fe581 | 348 | |
406034fa | 349 | if (have_cond_exec_flag) |
eb1c92fb | 350 | printf ("#define HAVE_conditional_execution 1\n"); |
7014838c | 351 | |
caef9864 | 352 | if (have_lo_sum_flag) |
eb1c92fb | 353 | printf ("#define HAVE_lo_sum 1\n"); |
6cc3d6ec | 354 | else |
355 | printf ("#define HAVE_lo_sum 0\n"); | |
caef9864 | 356 | |
9da3143a | 357 | if (have_rotate_flag) |
358 | printf ("#define HAVE_rotate 1\n"); | |
359 | ||
360 | if (have_rotatert_flag) | |
361 | printf ("#define HAVE_rotatert 1\n"); | |
362 | ||
82575fa7 | 363 | if (have_peephole_flag) |
eb1c92fb | 364 | printf ("#define HAVE_peephole 1\n"); |
211a5d90 | 365 | else |
366 | printf ("#define HAVE_peephole 0\n"); | |
82575fa7 | 367 | |
368 | if (have_peephole2_flag) | |
3e9f1237 | 369 | { |
370 | printf ("#define HAVE_peephole2 1\n"); | |
371 | printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2); | |
372 | } | |
82575fa7 | 373 | |
9af5ce0c | 374 | puts ("\n#endif /* GCC_INSN_CONFIG_H */"); |
d0c809e1 | 375 | |
376 | if (ferror (stdout) || fflush (stdout) || fclose (stdout)) | |
377 | return FATAL_EXIT_CODE; | |
378 | ||
379 | return SUCCESS_EXIT_CODE; | |
caef9864 | 380 | } |