1 /* Generate from machine description:
2 - some #define configuration flags.
3 Copyright (C) 1987-2013 Free Software Foundation, Inc.
5 This file is part of GCC.
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
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
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/>. */
24 #include "coretypes.h"
28 #include "gensupport.h"
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
;
39 static int have_peephole_flag
;
40 static int have_peephole2_flag
;
42 /* Maximum number of insns seen in a split. */
43 static int max_insns_per_split
= 1;
45 /* Maximum number of input insns for peephole2. */
46 static int max_insns_per_peep2
;
48 static int clobbers_seen_this_insn
;
49 static int dup_operands_seen_this_insn
;
51 static void walk_insn_part (rtx
, int, int);
52 static void gen_insn (rtx
);
53 static void gen_expand (rtx
);
54 static void gen_split (rtx
);
55 static void gen_peephole (rtx
);
56 static void gen_peephole2 (rtx
);
58 /* RECOG_P will be nonzero if this pattern was seen in a context where it will
59 be used to recognize, rather than just generate an insn.
61 NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC
62 of a SET whose destination is not (pc). */
65 walk_insn_part (rtx part
, int recog_p
, int non_pc_set_src
)
69 const char *format_ptr
;
74 code
= GET_CODE (part
);
78 clobbers_seen_this_insn
++;
82 if (XINT (part
, 0) > max_recog_operands
)
83 max_recog_operands
= XINT (part
, 0);
88 ++dup_operands_seen_this_insn
;
92 if (XINT (part
, 0) > max_recog_operands
)
93 max_recog_operands
= XINT (part
, 0);
94 /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
99 if (GET_CODE (XEXP (part
, 0)) == MATCH_OPERAND
100 || GET_CODE (XEXP (part
, 0)) == MATCH_DUP
)
105 ++dup_operands_seen_this_insn
;
106 if (XINT (part
, 0) > max_recog_operands
)
107 max_recog_operands
= XINT (part
, 0);
117 have_lo_sum_flag
= 1;
121 walk_insn_part (SET_DEST (part
), 0, recog_p
);
122 walk_insn_part (SET_SRC (part
), recog_p
,
123 GET_CODE (SET_DEST (part
)) != PC
);
127 /* Only consider this machine as having a conditional move if the
128 two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise,
129 we have some specific IF_THEN_ELSE construct (like the doz
130 instruction on the RS/6000) that can't be used in the general
131 context we want it for. */
133 if (recog_p
&& non_pc_set_src
134 && GET_CODE (XEXP (part
, 1)) == MATCH_OPERAND
135 && GET_CODE (XEXP (part
, 2)) == MATCH_OPERAND
)
141 have_cond_exec_flag
= 1;
144 case REG
: case CONST_INT
: case SYMBOL_REF
:
152 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
154 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
155 switch (*format_ptr
++)
159 walk_insn_part (XEXP (part
, i
), recog_p
, non_pc_set_src
);
162 if (XVEC (part
, i
) != NULL
)
163 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
164 walk_insn_part (XVECEXP (part
, i
, j
), recog_p
, non_pc_set_src
);
174 /* Walk the insn pattern to gather the #define's status. */
175 clobbers_seen_this_insn
= 0;
176 dup_operands_seen_this_insn
= 0;
177 if (XVEC (insn
, 1) != 0)
178 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
179 walk_insn_part (XVECEXP (insn
, 1, i
), 1, 0);
181 if (clobbers_seen_this_insn
> max_clobbers_per_insn
)
182 max_clobbers_per_insn
= clobbers_seen_this_insn
;
183 if (dup_operands_seen_this_insn
> max_dup_operands
)
184 max_dup_operands
= dup_operands_seen_this_insn
;
187 /* Similar but scan a define_expand. */
190 gen_expand (rtx insn
)
194 /* Walk the insn pattern to gather the #define's status. */
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
++)
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;
206 walk_insn_part (XVECEXP (insn
, 1, i
), 0, 0);
208 if (clobbers_seen_this_insn
> max_clobbers_per_insn
)
209 max_clobbers_per_insn
= clobbers_seen_this_insn
;
213 /* Similar but scan a define_split. */
216 gen_split (rtx split
)
220 /* Look through the patterns that are matched
221 to compute the maximum operand number. */
222 for (i
= 0; i
< XVECLEN (split
, 0); i
++)
223 walk_insn_part (XVECEXP (split
, 0, i
), 1, 0);
224 /* Look at the number of insns this insn could split into. */
225 if (XVECLEN (split
, 2) > max_insns_per_split
)
226 max_insns_per_split
= XVECLEN (split
, 2);
230 gen_peephole (rtx peep
)
234 /* Look through the patterns that are matched
235 to compute the maximum operand number. */
236 for (i
= 0; i
< XVECLEN (peep
, 0); i
++)
237 walk_insn_part (XVECEXP (peep
, 0, i
), 1, 0);
241 gen_peephole2 (rtx peep
)
245 /* Look through the patterns that are matched
246 to compute the maximum operand number. */
247 for (i
= XVECLEN (peep
, 0) - 1; i
>= 0; --i
)
248 walk_insn_part (XVECEXP (peep
, 0, i
), 1, 0);
250 /* Look at the number of insns this insn can be matched from. */
251 for (i
= XVECLEN (peep
, 0) - 1, n
= 0; i
>= 0; --i
)
252 if (GET_CODE (XVECEXP (peep
, 0, i
)) != MATCH_DUP
253 && GET_CODE (XVECEXP (peep
, 0, i
)) != MATCH_SCRATCH
)
255 if (n
> max_insns_per_peep2
)
256 max_insns_per_peep2
= n
;
260 main (int argc
, char **argv
)
264 progname
= "genconfig";
266 if (!init_rtx_reader_args (argc
, argv
))
267 return (FATAL_EXIT_CODE
);
269 puts ("/* Generated automatically by the program `genconfig'");
270 puts (" from the machine description file `md'. */\n");
271 puts ("#ifndef GCC_INSN_CONFIG_H");
272 puts ("#define GCC_INSN_CONFIG_H\n");
274 /* Allow at least 30 operands for the sake of asm constructs. */
275 /* ??? We *really* ought to reorganize things such that there
276 is no fixed upper bound. */
277 max_recog_operands
= 29; /* We will add 1 later. */
278 max_dup_operands
= 1;
280 /* Read the machine description. */
284 int line_no
, insn_code_number
= 0;
286 desc
= read_md_rtx (&line_no
, &insn_code_number
);
290 switch (GET_CODE (desc
))
304 case DEFINE_PEEPHOLE2
:
305 have_peephole2_flag
= 1;
306 gen_peephole2 (desc
);
309 case DEFINE_PEEPHOLE
:
310 have_peephole_flag
= 1;
319 printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands
+ 1);
320 printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands
);
322 /* This is conditionally defined, in case the user writes code which emits
323 more splits than we can readily see (and knows s/he does it). */
324 printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
325 printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split
);
330 printf ("#define HAVE_cc0 1\n");
331 printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");
335 /* We output CC0_P this way to make sure that X is declared
337 printf ("#define CC0_P(X) ((X) ? 0 : 0)\n");
341 printf ("#define HAVE_conditional_move 1\n");
343 if (have_cond_exec_flag
)
344 printf ("#define HAVE_conditional_execution 1\n");
346 if (have_lo_sum_flag
)
347 printf ("#define HAVE_lo_sum 1\n");
349 if (have_peephole_flag
)
350 printf ("#define HAVE_peephole 1\n");
352 if (have_peephole2_flag
)
354 printf ("#define HAVE_peephole2 1\n");
355 printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2
);
358 puts ("\n#endif /* GCC_INSN_CONFIG_H */");
360 if (ferror (stdout
) || fflush (stdout
) || fclose (stdout
))
361 return FATAL_EXIT_CODE
;
363 return SUCCESS_EXIT_CODE
;