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