1 /* Generate from machine description:
3 - some #define configuration flags.
4 Copyright (C) 1987, 1991 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
28 static struct obstack obstack
;
29 struct obstack
*rtl_obstack
= &obstack
;
31 #define obstack_chunk_alloc xmalloc
32 #define obstack_chunk_free free
35 extern rtx
read_rtx ();
37 /* flags to determine output of machine description dependent #define's. */
38 static int max_recog_operands
; /* Largest operand number seen. */
39 static int max_dup_operands
; /* Largest number of match_dup in any insn. */
40 static int max_clobbers_per_insn
;
41 static int register_constraint_flag
;
42 static int have_cc0_flag
;
43 static int have_cmove_flag
;
44 static int have_lo_sum_flag
;
46 /* Maximum number of insns seen in a split. */
47 static int max_insns_per_split
= 1;
49 static int clobbers_seen_this_insn
;
50 static int dup_operands_seen_this_insn
;
56 /* RECOG_P will be non-zero if this pattern was seen in a context where it will
57 be used to recognize, rather than just generate an insn.
59 NON_PC_SET_SRC will be non-zero if this pattern was seen in a SET_SRC
60 of a SET whose destination is not (pc). */
63 walk_insn_part (part
, recog_p
, non_pc_set_src
)
69 register RTX_CODE code
;
70 register char *format_ptr
;
75 code
= GET_CODE (part
);
79 clobbers_seen_this_insn
++;
83 if (XINT (part
, 0) > max_recog_operands
)
84 max_recog_operands
= XINT (part
, 0);
85 if (XSTR (part
, 2) && *XSTR (part
, 2))
86 register_constraint_flag
= 1;
91 ++dup_operands_seen_this_insn
;
95 if (XINT (part
, 0) > max_recog_operands
)
96 max_recog_operands
= XINT (part
, 0);
97 /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
102 if (GET_CODE (XEXP (part
, 0)) == MATCH_OPERAND
)
107 ++dup_operands_seen_this_insn
;
108 if (XINT (part
, 0) > max_recog_operands
)
109 max_recog_operands
= XINT (part
, 0);
119 have_lo_sum_flag
= 1;
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
);
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
133 context we want it for. */
135 if (recog_p
&& non_pc_set_src
136 && GET_CODE (XEXP (part
, 1)) == MATCH_OPERAND
137 && GET_CODE (XEXP (part
, 2)) == MATCH_OPERAND
)
141 case REG
: case CONST_INT
: case SYMBOL_REF
:
146 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
148 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
149 switch (*format_ptr
++)
153 walk_insn_part (XEXP (part
, i
), recog_p
, non_pc_set_src
);
156 if (XVEC (part
, i
) != NULL
)
157 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
158 walk_insn_part (XVECEXP (part
, i
, j
), recog_p
, non_pc_set_src
);
169 /* Walk the insn pattern to gather the #define's status. */
170 clobbers_seen_this_insn
= 0;
171 dup_operands_seen_this_insn
= 0;
172 if (XVEC (insn
, 1) != 0)
173 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
174 walk_insn_part (XVECEXP (insn
, 1, i
), 1, 0);
176 if (clobbers_seen_this_insn
> max_clobbers_per_insn
)
177 max_clobbers_per_insn
= clobbers_seen_this_insn
;
178 if (dup_operands_seen_this_insn
> max_dup_operands
)
179 max_dup_operands
= dup_operands_seen_this_insn
;
182 /* Similar but scan a define_expand. */
190 /* Walk the insn pattern to gather the #define's status. */
192 /* Note that we don't bother recording the number of MATCH_DUPs
193 that occur in a gen_expand, because only reload cares about that. */
194 if (XVEC (insn
, 1) != 0)
195 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
197 /* Compute the maximum SETs and CLOBBERS
198 in any one of the sub-insns;
199 don't sum across all of them. */
200 clobbers_seen_this_insn
= 0;
202 walk_insn_part (XVECEXP (insn
, 1, i
), 0, 0);
204 if (clobbers_seen_this_insn
> max_clobbers_per_insn
)
205 max_clobbers_per_insn
= clobbers_seen_this_insn
;
209 /* Similar but scan a define_split. */
217 /* Look through the patterns that are matched
218 to compute the maximum operand number. */
219 for (i
= 0; i
< XVECLEN (split
, 0); i
++)
220 walk_insn_part (XVECEXP (split
, 0, i
), 1, 0);
221 /* Look at the number of insns this insn could split into. */
222 if (XVECLEN (split
, 2) > max_insns_per_split
)
223 max_insns_per_split
= XVECLEN (split
, 2);
232 /* Look through the patterns that are matched
233 to compute the maximum operand number. */
234 for (i
= 0; i
< XVECLEN (peep
, 0); i
++)
235 walk_insn_part (XVECEXP (peep
, 0, i
), 1, 0);
242 register char *val
= (char *) malloc (size
);
245 fatal ("virtual memory exhausted");
255 char *result
= (char *) realloc (ptr
, size
);
257 fatal ("virtual memory exhausted");
265 fprintf (stderr
, "genconfig: ");
266 fprintf (stderr
, s
, a1
, a2
);
267 fprintf (stderr
, "\n");
268 exit (FATAL_EXIT_CODE
);
271 /* More 'friendly' abort that prints the line and file.
272 config.h can #define abort fancy_abort if you like that sort of thing. */
277 fatal ("Internal gcc abort.");
289 obstack_init (rtl_obstack
);
292 fatal ("No input file name.");
294 infile
= fopen (argv
[1], "r");
298 exit (FATAL_EXIT_CODE
);
303 printf ("/* Generated automatically by the program `genconfig'\n\
304 from the machine description file `md'. */\n\n");
306 /* Allow at least 10 operands for the sake of asm constructs. */
307 max_recog_operands
= 9; /* We will add 1 later. */
308 max_dup_operands
= 1;
310 /* Read the machine description. */
314 c
= read_skip_spaces (infile
);
319 desc
= read_rtx (infile
);
320 if (GET_CODE (desc
) == DEFINE_INSN
)
322 if (GET_CODE (desc
) == DEFINE_EXPAND
)
324 if (GET_CODE (desc
) == DEFINE_SPLIT
)
326 if (GET_CODE (desc
) == DEFINE_PEEPHOLE
)
330 printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands
+ 1);
332 printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands
);
334 /* This is conditionally defined, in case the user writes code which emits
335 more splits than we can readily see (and knows s/he does it). */
336 printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n",
337 max_insns_per_split
);
339 if (register_constraint_flag
)
340 printf ("#define REGISTER_CONSTRAINTS\n");
343 printf ("#define HAVE_cc0\n");
347 /* ??? The #ifndef/#endif is a hack for targets like sparc where
348 conditional moves don't exist for all versions of the
349 architecture. This won't be needed after conditional move support
350 has been clean up. */
351 printf ("#ifndef HAVE_conditional_move\n");
352 printf ("#define HAVE_conditional_move 1\n");
356 if (have_lo_sum_flag
)
357 printf ("#define HAVE_lo_sum\n");
360 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);