(distribute_notes, case REG_DEAD): If a call uses a
[official-gcc.git] / gcc / genconfig.c
blobf1585c6f169153216a8f030d4bea00bcff697374
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)
11 any later version.
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. */
23 #include <stdio.h>
24 #include "hconfig.h"
25 #include "rtl.h"
26 #include "obstack.h"
28 static struct obstack obstack;
29 struct obstack *rtl_obstack = &obstack;
31 #define obstack_chunk_alloc xmalloc
32 #define obstack_chunk_free free
34 extern void 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;
52 char *xmalloc ();
53 static void fatal ();
54 void fancy_abort ();
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). */
62 static void
63 walk_insn_part (part, recog_p, non_pc_set_src)
64 rtx part;
65 int recog_p;
66 int non_pc_set_src;
68 register int i, j;
69 register RTX_CODE code;
70 register char *format_ptr;
72 if (part == 0)
73 return;
75 code = GET_CODE (part);
76 switch (code)
78 case CLOBBER:
79 clobbers_seen_this_insn++;
80 break;
82 case MATCH_OPERAND:
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;
87 return;
89 case MATCH_OP_DUP:
90 case MATCH_PAR_DUP:
91 ++dup_operands_seen_this_insn;
92 case MATCH_SCRATCH:
93 case MATCH_PARALLEL:
94 case MATCH_OPERATOR:
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
98 MATCH_PARALLEL. */
99 break;
101 case LABEL_REF:
102 if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
103 break;
104 return;
106 case MATCH_DUP:
107 ++dup_operands_seen_this_insn;
108 if (XINT (part, 0) > max_recog_operands)
109 max_recog_operands = XINT (part, 0);
110 return;
112 case CC0:
113 if (recog_p)
114 have_cc0_flag = 1;
115 return;
117 case LO_SUM:
118 if (recog_p)
119 have_lo_sum_flag = 1;
120 return;
122 case SET:
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);
126 return;
128 case IF_THEN_ELSE:
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)
138 have_cmove_flag = 1;
139 break;
141 case REG: case CONST_INT: case SYMBOL_REF:
142 case PC:
143 return;
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++)
151 case 'e':
152 case 'u':
153 walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
154 break;
155 case 'E':
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);
159 break;
163 static void
164 gen_insn (insn)
165 rtx insn;
167 int i;
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. */
184 static void
185 gen_expand (insn)
186 rtx insn;
188 int i;
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. */
211 static void
212 gen_split (split)
213 rtx split;
215 int i;
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);
226 static void
227 gen_peephole (peep)
228 rtx peep;
230 int i;
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);
238 char *
239 xmalloc (size)
240 unsigned size;
242 register char *val = (char *) malloc (size);
244 if (val == 0)
245 fatal ("virtual memory exhausted");
247 return val;
250 char *
251 xrealloc (ptr, size)
252 char *ptr;
253 unsigned size;
255 char *result = (char *) realloc (ptr, size);
256 if (!result)
257 fatal ("virtual memory exhausted");
258 return result;
261 static void
262 fatal (s, a1, a2)
263 char *s;
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. */
274 void
275 fancy_abort ()
277 fatal ("Internal gcc abort.");
281 main (argc, argv)
282 int argc;
283 char **argv;
285 rtx desc;
286 FILE *infile;
287 register int c;
289 obstack_init (rtl_obstack);
291 if (argc <= 1)
292 fatal ("No input file name.");
294 infile = fopen (argv[1], "r");
295 if (infile == 0)
297 perror (argv[1]);
298 exit (FATAL_EXIT_CODE);
301 init_rtl ();
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. */
312 while (1)
314 c = read_skip_spaces (infile);
315 if (c == EOF)
316 break;
317 ungetc (c, infile);
319 desc = read_rtx (infile);
320 if (GET_CODE (desc) == DEFINE_INSN)
321 gen_insn (desc);
322 if (GET_CODE (desc) == DEFINE_EXPAND)
323 gen_expand (desc);
324 if (GET_CODE (desc) == DEFINE_SPLIT)
325 gen_split (desc);
326 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
327 gen_peephole (desc);
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");
342 if (have_cc0_flag)
343 printf ("#define HAVE_cc0\n");
345 if (have_cmove_flag)
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");
353 printf ("#endif\n");
356 if (have_lo_sum_flag)
357 printf ("#define HAVE_lo_sum\n");
359 fflush (stdout);
360 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
361 /* NOTREACHED */
362 return 0;