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