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