Mercurial > hg > CbC > CbC_gcc
annotate gcc/genconfig.c @ 123:ab229f40eab2
fix inline_call
author | mir3636 |
---|---|
date | Fri, 30 Mar 2018 22:58:55 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Generate from machine description: |
2 - some #define configuration flags. | |
111 | 3 Copyright (C) 1987-2017 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: | |
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); | |
81 return; | |
82 | |
83 case MATCH_OP_DUP: | |
84 case MATCH_PAR_DUP: | |
85 ++dup_operands_seen_this_insn; | |
111 | 86 /* FALLTHRU */ |
0 | 87 case MATCH_SCRATCH: |
88 case MATCH_PARALLEL: | |
89 case MATCH_OPERATOR: | |
90 if (XINT (part, 0) > max_recog_operands) | |
91 max_recog_operands = XINT (part, 0); | |
92 /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or | |
93 MATCH_PARALLEL. */ | |
94 break; | |
95 | |
96 case LABEL_REF: | |
97 if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND | |
98 || GET_CODE (XEXP (part, 0)) == MATCH_DUP) | |
99 break; | |
100 return; | |
101 | |
102 case MATCH_DUP: | |
103 ++dup_operands_seen_this_insn; | |
104 if (XINT (part, 0) > max_recog_operands) | |
105 max_recog_operands = XINT (part, 0); | |
106 return; | |
107 | |
108 case CC0: | |
109 if (recog_p) | |
110 have_cc0_flag = 1; | |
111 return; | |
112 | |
113 case LO_SUM: | |
114 if (recog_p) | |
115 have_lo_sum_flag = 1; | |
116 return; | |
117 | |
111 | 118 case ROTATE: |
119 if (recog_p) | |
120 have_rotate_flag = 1; | |
121 return; | |
122 | |
123 case ROTATERT: | |
124 if (recog_p) | |
125 have_rotatert_flag = 1; | |
126 return; | |
127 | |
0 | 128 case SET: |
129 walk_insn_part (SET_DEST (part), 0, recog_p); | |
130 walk_insn_part (SET_SRC (part), recog_p, | |
131 GET_CODE (SET_DEST (part)) != PC); | |
132 return; | |
133 | |
134 case IF_THEN_ELSE: | |
135 /* Only consider this machine as having a conditional move if the | |
136 two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, | |
137 we have some specific IF_THEN_ELSE construct (like the doz | |
138 instruction on the RS/6000) that can't be used in the general | |
139 context we want it for. */ | |
140 | |
141 if (recog_p && non_pc_set_src | |
142 && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND | |
143 && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) | |
144 have_cmove_flag = 1; | |
145 break; | |
146 | |
147 case COND_EXEC: | |
148 if (recog_p) | |
149 have_cond_exec_flag = 1; | |
150 break; | |
151 | |
152 case REG: case CONST_INT: case SYMBOL_REF: | |
153 case PC: | |
154 return; | |
155 | |
156 default: | |
157 break; | |
158 } | |
159 | |
160 format_ptr = GET_RTX_FORMAT (GET_CODE (part)); | |
161 | |
162 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) | |
163 switch (*format_ptr++) | |
164 { | |
165 case 'e': | |
166 case 'u': | |
167 walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); | |
168 break; | |
169 case 'E': | |
170 if (XVEC (part, i) != NULL) | |
171 for (j = 0; j < XVECLEN (part, i); j++) | |
172 walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); | |
173 break; | |
174 } | |
175 } | |
176 | |
177 static void | |
111 | 178 gen_insn (md_rtx_info *info) |
0 | 179 { |
180 int i; | |
181 | |
182 /* Walk the insn pattern to gather the #define's status. */ | |
111 | 183 rtx insn = info->def; |
0 | 184 clobbers_seen_this_insn = 0; |
185 dup_operands_seen_this_insn = 0; | |
186 if (XVEC (insn, 1) != 0) | |
187 for (i = 0; i < XVECLEN (insn, 1); i++) | |
188 walk_insn_part (XVECEXP (insn, 1, i), 1, 0); | |
189 | |
190 if (clobbers_seen_this_insn > max_clobbers_per_insn) | |
191 max_clobbers_per_insn = clobbers_seen_this_insn; | |
192 if (dup_operands_seen_this_insn > max_dup_operands) | |
193 max_dup_operands = dup_operands_seen_this_insn; | |
194 } | |
195 | |
196 /* Similar but scan a define_expand. */ | |
197 | |
198 static void | |
111 | 199 gen_expand (md_rtx_info *info) |
0 | 200 { |
201 int i; | |
202 | |
203 /* Walk the insn pattern to gather the #define's status. */ | |
204 | |
205 /* Note that we don't bother recording the number of MATCH_DUPs | |
206 that occur in a gen_expand, because only reload cares about that. */ | |
111 | 207 rtx insn = info->def; |
0 | 208 if (XVEC (insn, 1) != 0) |
209 for (i = 0; i < XVECLEN (insn, 1); i++) | |
210 { | |
211 /* Compute the maximum SETs and CLOBBERS | |
212 in any one of the sub-insns; | |
213 don't sum across all of them. */ | |
214 clobbers_seen_this_insn = 0; | |
215 | |
216 walk_insn_part (XVECEXP (insn, 1, i), 0, 0); | |
217 | |
218 if (clobbers_seen_this_insn > max_clobbers_per_insn) | |
219 max_clobbers_per_insn = clobbers_seen_this_insn; | |
220 } | |
221 } | |
222 | |
223 /* Similar but scan a define_split. */ | |
224 | |
225 static void | |
111 | 226 gen_split (md_rtx_info *info) |
0 | 227 { |
228 int i; | |
229 | |
230 /* Look through the patterns that are matched | |
231 to compute the maximum operand number. */ | |
111 | 232 rtx split = info->def; |
0 | 233 for (i = 0; i < XVECLEN (split, 0); i++) |
234 walk_insn_part (XVECEXP (split, 0, i), 1, 0); | |
235 /* Look at the number of insns this insn could split into. */ | |
236 if (XVECLEN (split, 2) > max_insns_per_split) | |
237 max_insns_per_split = XVECLEN (split, 2); | |
238 } | |
239 | |
240 static void | |
111 | 241 gen_peephole (md_rtx_info *info) |
0 | 242 { |
243 int i; | |
244 | |
245 /* Look through the patterns that are matched | |
246 to compute the maximum operand number. */ | |
111 | 247 rtx peep = info->def; |
0 | 248 for (i = 0; i < XVECLEN (peep, 0); i++) |
249 walk_insn_part (XVECEXP (peep, 0, i), 1, 0); | |
250 } | |
251 | |
252 static void | |
111 | 253 gen_peephole2 (md_rtx_info *info) |
0 | 254 { |
255 int i, n; | |
256 | |
257 /* Look through the patterns that are matched | |
258 to compute the maximum operand number. */ | |
111 | 259 rtx peep = info->def; |
0 | 260 for (i = XVECLEN (peep, 0) - 1; i >= 0; --i) |
261 walk_insn_part (XVECEXP (peep, 0, i), 1, 0); | |
262 | |
263 /* Look at the number of insns this insn can be matched from. */ | |
264 for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i) | |
265 if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP | |
266 && GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH) | |
267 n++; | |
268 if (n > max_insns_per_peep2) | |
269 max_insns_per_peep2 = n; | |
270 } | |
271 | |
272 int | |
111 | 273 main (int argc, const char **argv) |
0 | 274 { |
275 progname = "genconfig"; | |
276 | |
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
|
277 if (!init_rtx_reader_args (argc, argv)) |
0 | 278 return (FATAL_EXIT_CODE); |
279 | |
280 puts ("/* Generated automatically by the program `genconfig'"); | |
281 puts (" from the machine description file `md'. */\n"); | |
282 puts ("#ifndef GCC_INSN_CONFIG_H"); | |
283 puts ("#define GCC_INSN_CONFIG_H\n"); | |
284 | |
285 /* Allow at least 30 operands for the sake of asm constructs. */ | |
286 /* ??? We *really* ought to reorganize things such that there | |
287 is no fixed upper bound. */ | |
288 max_recog_operands = 29; /* We will add 1 later. */ | |
289 max_dup_operands = 1; | |
290 | |
291 /* Read the machine description. */ | |
292 | |
111 | 293 md_rtx_info info; |
294 while (read_md_rtx (&info)) | |
295 switch (GET_CODE (info.def)) | |
296 { | |
297 case DEFINE_INSN: | |
298 gen_insn (&info); | |
299 break; | |
0 | 300 |
111 | 301 case DEFINE_EXPAND: |
302 gen_expand (&info); | |
0 | 303 break; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
304 |
111 | 305 case DEFINE_SPLIT: |
306 gen_split (&info); | |
307 break; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
308 |
111 | 309 case DEFINE_PEEPHOLE2: |
310 have_peephole2_flag = 1; | |
311 gen_peephole2 (&info); | |
312 break; | |
0 | 313 |
111 | 314 case DEFINE_PEEPHOLE: |
315 have_peephole_flag = 1; | |
316 gen_peephole (&info); | |
317 break; | |
0 | 318 |
111 | 319 default: |
320 break; | |
321 } | |
0 | 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 the user writes code which emits | |
327 more splits than we can readily see (and knows 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 /* We output CC0_P this way to make sure that X is declared | |
340 somewhere. */ | |
111 | 341 printf ("#define HAVE_cc0 0\n"); |
0 | 342 printf ("#define CC0_P(X) ((X) ? 0 : 0)\n"); |
343 } | |
344 | |
345 if (have_cmove_flag) | |
346 printf ("#define HAVE_conditional_move 1\n"); | |
111 | 347 else |
348 printf ("#define HAVE_conditional_move 0\n"); | |
0 | 349 |
350 if (have_cond_exec_flag) | |
351 printf ("#define HAVE_conditional_execution 1\n"); | |
111 | 352 else |
353 printf ("#define HAVE_conditional_execution 0\n"); | |
0 | 354 |
355 if (have_lo_sum_flag) | |
356 printf ("#define HAVE_lo_sum 1\n"); | |
111 | 357 else |
358 printf ("#define HAVE_lo_sum 0\n"); | |
359 | |
360 if (have_rotate_flag) | |
361 printf ("#define HAVE_rotate 1\n"); | |
362 | |
363 if (have_rotatert_flag) | |
364 printf ("#define HAVE_rotatert 1\n"); | |
0 | 365 |
366 if (have_peephole_flag) | |
367 printf ("#define HAVE_peephole 1\n"); | |
111 | 368 else |
369 printf ("#define HAVE_peephole 0\n"); | |
0 | 370 |
371 if (have_peephole2_flag) | |
372 { | |
373 printf ("#define HAVE_peephole2 1\n"); | |
374 printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2); | |
375 } | |
111 | 376 else |
377 { | |
378 printf ("#define HAVE_peephole2 0\n"); | |
379 printf ("#define MAX_INSNS_PER_PEEP2 0\n"); | |
380 } | |
0 | 381 |
111 | 382 puts ("\n#endif /* GCC_INSN_CONFIG_H */"); |
0 | 383 |
384 if (ferror (stdout) || fflush (stdout) || fclose (stdout)) | |
385 return FATAL_EXIT_CODE; | |
386 | |
387 return SUCCESS_EXIT_CODE; | |
388 } |