]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genconfig.c
genopinit.c: Use $ for escape sequences in optab patterns.
[thirdparty/gcc.git] / gcc / genconfig.c
CommitLineData
aabf90e8 1/* Generate from machine description:
aabf90e8 2 - some #define configuration flags.
d050d723
JL
3 Copyright (C) 1987, 1991, 1997, 1998,
4 1999, 2000 Free Software Foundation, Inc.
aabf90e8
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
a35311b0
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
aabf90e8
RK
22
23
0d64891c 24#include "hconfig.h"
0b93b64e 25#include "system.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
32static int max_recog_operands; /* Largest operand number seen. */
33static int max_dup_operands; /* Largest number of match_dup in any insn. */
aabf90e8 34static int max_clobbers_per_insn;
aabf90e8 35static int have_cc0_flag;
674ba2d6 36static int have_cmove_flag;
0c99ec5c 37static int have_cond_exec_flag;
aabf90e8 38static int have_lo_sum_flag;
ede7cd44
RH
39static int have_peephole_flag;
40static int have_peephole2_flag;
aabf90e8
RK
41
42/* Maximum number of insns seen in a split. */
43static int max_insns_per_split = 1;
44
45static int clobbers_seen_this_insn;
46static int dup_operands_seen_this_insn;
47
a94ae8f5
KG
48static void walk_insn_part PARAMS ((rtx, int, int));
49static void gen_insn PARAMS ((rtx));
50static void gen_expand PARAMS ((rtx));
51static void gen_split PARAMS ((rtx));
52static void gen_peephole PARAMS ((rtx));
56c0e996 53
aabf90e8 54/* RECOG_P will be non-zero if this pattern was seen in a context where it will
674ba2d6
RK
55 be used to recognize, rather than just generate an insn.
56
57 NON_PC_SET_SRC will be non-zero if this pattern was seen in a SET_SRC
58 of a SET whose destination is not (pc). */
aabf90e8
RK
59
60static void
674ba2d6 61walk_insn_part (part, recog_p, non_pc_set_src)
aabf90e8 62 rtx part;
674ba2d6
RK
63 int recog_p;
64 int non_pc_set_src;
aabf90e8
RK
65{
66 register int i, j;
67 register RTX_CODE code;
6f7d635c 68 register const char *format_ptr;
aabf90e8
RK
69
70 if (part == 0)
71 return;
72
73 code = GET_CODE (part);
74 switch (code)
75 {
76 case CLOBBER:
77 clobbers_seen_this_insn++;
78 break;
79
80 case MATCH_OPERAND:
81 if (XINT (part, 0) > max_recog_operands)
82 max_recog_operands = XINT (part, 0);
aabf90e8
RK
83 return;
84
85 case MATCH_OP_DUP:
13ed0ef0 86 case MATCH_PAR_DUP:
aabf90e8
RK
87 ++dup_operands_seen_this_insn;
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 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
674ba2d6
RK
118 case SET:
119 walk_insn_part (SET_DEST (part), 0, recog_p);
120 walk_insn_part (SET_SRC (part), recog_p,
121 GET_CODE (SET_DEST (part)) != PC);
122 return;
123
124 case IF_THEN_ELSE:
9e87cc89
RK
125 /* Only consider this machine as having a conditional move if the
126 two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise,
127 we have some specific IF_THEN_ELSE construct (like the doz
128 instruction on the RS/6000) that can't be used in the general
0c99ec5c 129 context we want it for. */
9e87cc89
RK
130
131 if (recog_p && non_pc_set_src
132 && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
133 && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
674ba2d6 134 have_cmove_flag = 1;
0c99ec5c
RH
135 break;
136
137 case COND_EXEC:
138 if (recog_p)
139 have_cond_exec_flag = 1;
674ba2d6
RK
140 break;
141
aabf90e8
RK
142 case REG: case CONST_INT: case SYMBOL_REF:
143 case PC:
144 return;
ccd043a9
RL
145
146 default:
147 break;
aabf90e8
RK
148 }
149
150 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
151
152 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
153 switch (*format_ptr++)
154 {
155 case 'e':
156 case 'u':
674ba2d6 157 walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
aabf90e8
RK
158 break;
159 case 'E':
160 if (XVEC (part, i) != NULL)
161 for (j = 0; j < XVECLEN (part, i); j++)
674ba2d6 162 walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
aabf90e8
RK
163 break;
164 }
165}
166
167static void
168gen_insn (insn)
169 rtx insn;
170{
171 int i;
172
173 /* Walk the insn pattern to gather the #define's status. */
174 clobbers_seen_this_insn = 0;
175 dup_operands_seen_this_insn = 0;
176 if (XVEC (insn, 1) != 0)
177 for (i = 0; i < XVECLEN (insn, 1); i++)
674ba2d6 178 walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
aabf90e8
RK
179
180 if (clobbers_seen_this_insn > max_clobbers_per_insn)
181 max_clobbers_per_insn = clobbers_seen_this_insn;
182 if (dup_operands_seen_this_insn > max_dup_operands)
183 max_dup_operands = dup_operands_seen_this_insn;
184}
185
186/* Similar but scan a define_expand. */
187
188static void
189gen_expand (insn)
190 rtx insn;
191{
192 int i;
193
194 /* Walk the insn pattern to gather the #define's status. */
195
196 /* Note that we don't bother recording the number of MATCH_DUPs
197 that occur in a gen_expand, because only reload cares about that. */
198 if (XVEC (insn, 1) != 0)
199 for (i = 0; i < XVECLEN (insn, 1); i++)
200 {
201 /* Compute the maximum SETs and CLOBBERS
202 in any one of the sub-insns;
203 don't sum across all of them. */
204 clobbers_seen_this_insn = 0;
205
674ba2d6 206 walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
aabf90e8
RK
207
208 if (clobbers_seen_this_insn > max_clobbers_per_insn)
209 max_clobbers_per_insn = clobbers_seen_this_insn;
210 }
211}
212
213/* Similar but scan a define_split. */
214
215static void
216gen_split (split)
217 rtx split;
218{
219 int i;
220
221 /* Look through the patterns that are matched
222 to compute the maximum operand number. */
223 for (i = 0; i < XVECLEN (split, 0); i++)
674ba2d6 224 walk_insn_part (XVECEXP (split, 0, i), 1, 0);
aabf90e8
RK
225 /* Look at the number of insns this insn could split into. */
226 if (XVECLEN (split, 2) > max_insns_per_split)
227 max_insns_per_split = XVECLEN (split, 2);
228}
229
230static void
231gen_peephole (peep)
232 rtx peep;
233{
234 int i;
235
236 /* Look through the patterns that are matched
237 to compute the maximum operand number. */
238 for (i = 0; i < XVECLEN (peep, 0); i++)
674ba2d6 239 walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
aabf90e8 240}
aabf90e8 241
a94ae8f5 242extern int main PARAMS ((int, char **));
c1b59dce 243
aabf90e8
RK
244int
245main (argc, argv)
246 int argc;
247 char **argv;
248{
249 rtx desc;
aabf90e8 250
f8b6598e 251 progname = "genconfig";
aabf90e8
RK
252
253 if (argc <= 1)
254 fatal ("No input file name.");
255
c88c0d42
CP
256 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
257 return (FATAL_EXIT_CODE);
aabf90e8 258
aabf90e8
RK
259 printf ("/* Generated automatically by the program `genconfig'\n\
260from the machine description file `md'. */\n\n");
261
262 /* Allow at least 10 operands for the sake of asm constructs. */
7b7bceeb 263 max_recog_operands = 9; /* We will add 1 later. */
aabf90e8
RK
264 max_dup_operands = 1;
265
266 /* Read the machine description. */
267
268 while (1)
269 {
c88c0d42
CP
270 int line_no, insn_code_number = 0;
271
272 desc = read_md_rtx (&line_no, &insn_code_number);
273 if (desc == NULL)
aabf90e8 274 break;
c88c0d42
CP
275
276 switch (GET_CODE (desc))
ede7cd44 277 {
c88c0d42
CP
278 case DEFINE_INSN:
279 gen_insn (desc);
280 break;
281
282 case DEFINE_EXPAND:
283 gen_expand (desc);
284 break;
285
286 case DEFINE_SPLIT:
287 gen_split (desc);
288 break;
289
290 case DEFINE_PEEPHOLE2:
291 have_peephole2_flag = 1;
292 gen_split (desc);
293 break;
294
295 case DEFINE_PEEPHOLE:
296 have_peephole_flag = 1;
297 gen_peephole (desc);
298 break;
299
300 default:
301 break;
ede7cd44 302 }
aabf90e8
RK
303 }
304
7b7bceeb 305 printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
aabf90e8
RK
306
307 printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
308
309 /* This is conditionally defined, in case the user writes code which emits
310 more splits than we can readily see (and knows s/he does it). */
0c99ec5c
RH
311 printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
312 printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
313 printf ("#endif\n");
aabf90e8 314
aabf90e8 315 if (have_cc0_flag)
0a2287bf 316 printf ("#define HAVE_cc0 1\n");
aabf90e8 317
674ba2d6 318 if (have_cmove_flag)
0a2287bf 319 printf ("#define HAVE_conditional_move 1\n");
674ba2d6 320
0c99ec5c 321 if (have_cond_exec_flag)
0a2287bf 322 printf ("#define HAVE_conditional_execution 1\n");
c5c76735 323
aabf90e8 324 if (have_lo_sum_flag)
0a2287bf 325 printf ("#define HAVE_lo_sum 1\n");
aabf90e8 326
ede7cd44 327 if (have_peephole_flag)
0a2287bf 328 printf ("#define HAVE_peephole 1\n");
ede7cd44
RH
329
330 if (have_peephole2_flag)
0a2287bf 331 printf ("#define HAVE_peephole2 1\n");
ede7cd44 332
aabf90e8 333 fflush (stdout);
c1b59dce 334 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
aabf90e8 335}
a995e389
RH
336
337/* Define this so we can link with print-rtl.o to get debug_rtx function. */
338const char *
339get_insn_name (code)
c1b59dce 340 int code ATTRIBUTE_UNUSED;
a995e389
RH
341{
342 return NULL;
343}