Undo June 11th change
[official-gcc.git] / gcc / genflags.c
blobd389a733e515746fe8d2b842e414f05e03c4df72
1 /* Generate from machine description:
3 - some flags HAVE_... saying which simple standard instructions are
4 available for this machine.
5 Copyright (C) 1987, 1991, 1995, 1998 Free Software Foundation, Inc.
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
25 #include "hconfig.h"
26 #ifdef __STDC__
27 #include <stdarg.h>
28 #else
29 #include <varargs.h>
30 #endif
31 #include "system.h"
32 #include "rtl.h"
33 #include "obstack.h"
35 static struct obstack obstack;
36 struct obstack *rtl_obstack = &obstack;
38 #define obstack_chunk_alloc xmalloc
39 #define obstack_chunk_free free
41 char *xmalloc PROTO((unsigned));
42 static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
43 void fancy_abort PROTO((void));
45 /* Names for patterns. Need to allow linking with print-rtl. */
46 char **insn_name_ptr;
48 /* Obstacks to remember normal, and call insns. */
49 static struct obstack call_obstack, normal_obstack;
51 /* Max size of names encountered. */
52 static int max_id_len;
54 static int num_operands PROTO((rtx));
55 static void gen_proto PROTO((rtx));
56 static void gen_nonproto PROTO((rtx));
57 static void gen_insn PROTO((rtx));
60 /* Count the number of match_operand's found. */
62 static int
63 num_operands (x)
64 rtx x;
66 int count = 0;
67 int i, j;
68 enum rtx_code code = GET_CODE (x);
69 char *format_ptr = GET_RTX_FORMAT (code);
71 if (code == MATCH_OPERAND)
72 return 1;
74 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
75 count++;
77 for (i = 0; i < GET_RTX_LENGTH (code); i++)
79 switch (*format_ptr++)
81 case 'u':
82 case 'e':
83 count += num_operands (XEXP (x, i));
84 break;
86 case 'E':
87 if (XVEC (x, i) != NULL)
88 for (j = 0; j < XVECLEN (x, i); j++)
89 count += num_operands (XVECEXP (x, i, j));
91 break;
95 return count;
98 /* Print out prototype information for a function. */
100 static void
101 gen_proto (insn)
102 rtx insn;
104 int num = num_operands (insn);
105 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
107 if (num == 0)
108 printf ("void");
109 else
111 while (num-- > 1)
112 printf ("rtx, ");
114 printf ("rtx");
117 printf ("));\n");
120 /* Print out a function declaration without a prototype. */
122 static void
123 gen_nonproto (insn)
124 rtx insn;
126 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
129 static void
130 gen_insn (insn)
131 rtx insn;
133 char *name = XSTR (insn, 0);
134 char *p;
135 struct obstack *obstack_ptr;
136 int len;
138 /* Don't mention instructions whose names are the null string
139 or begin with '*'. They are in the machine description just
140 to be recognized. */
141 if (name[0] == 0 || name[0] == '*')
142 return;
144 len = strlen (name);
146 if (len > max_id_len)
147 max_id_len = len;
149 printf ("#define HAVE_%s ", name);
150 if (strlen (XSTR (insn, 2)) == 0)
151 printf ("1\n");
152 else
154 /* Write the macro definition, putting \'s at the end of each line,
155 if more than one. */
156 printf ("(");
157 for (p = XSTR (insn, 2); *p; p++)
159 if (*p == '\n')
160 printf (" \\\n");
161 else
162 printf ("%c", *p);
164 printf (")\n");
167 /* Save the current insn, so that we can later put out appropriate
168 prototypes. At present, most md files have the wrong number of
169 arguments for the call insns (call, call_value, call_pop,
170 call_value_pop) ignoring the extra arguments that are passed for
171 some machines, so by default, turn off the prototype. */
173 obstack_ptr = (name[0] == 'c'
174 && (!strcmp (name, "call")
175 || !strcmp (name, "call_value")
176 || !strcmp (name, "call_pop")
177 || !strcmp (name, "call_value_pop")))
178 ? &call_obstack : &normal_obstack;
180 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
183 char *
184 xmalloc (size)
185 unsigned size;
187 register char *val = (char *) malloc (size);
189 if (val == 0)
190 fatal ("virtual memory exhausted");
192 return val;
195 char *
196 xrealloc (ptr, size)
197 char *ptr;
198 unsigned size;
200 char *result = (char *) realloc (ptr, size);
201 if (!result)
202 fatal ("virtual memory exhausted");
203 return result;
206 static void
207 fatal VPROTO ((char *format, ...))
209 #ifndef __STDC__
210 char *format;
211 #endif
212 va_list ap;
214 VA_START (ap, format);
216 #ifndef __STDC__
217 format = va_arg (ap, char *);
218 #endif
220 fprintf (stderr, "genflags: ");
221 vfprintf (stderr, format, ap);
222 va_end (ap);
223 fprintf (stderr, "\n");
224 exit (FATAL_EXIT_CODE);
227 /* More 'friendly' abort that prints the line and file.
228 config.h can #define abort fancy_abort if you like that sort of thing. */
230 void
231 fancy_abort ()
233 fatal ("Internal gcc abort.");
237 main (argc, argv)
238 int argc;
239 char **argv;
241 rtx desc;
242 rtx dummy;
243 rtx *call_insns;
244 rtx *normal_insns;
245 rtx *insn_ptr;
246 FILE *infile;
247 register int c;
249 obstack_init (rtl_obstack);
250 obstack_init (&call_obstack);
251 obstack_init (&normal_obstack);
253 if (argc <= 1)
254 fatal ("No input file name.");
256 infile = fopen (argv[1], "r");
257 if (infile == 0)
259 perror (argv[1]);
260 exit (FATAL_EXIT_CODE);
263 init_rtl ();
265 printf ("/* Generated automatically by the program `genflags'\n\
266 from the machine description file `md'. */\n\n");
268 /* Read the machine description. */
270 while (1)
272 c = read_skip_spaces (infile);
273 if (c == EOF)
274 break;
275 ungetc (c, infile);
277 desc = read_rtx (infile);
278 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
279 gen_insn (desc);
282 /* Print out the prototypes now. */
283 dummy = (rtx) 0;
284 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
285 call_insns = (rtx *) obstack_finish (&call_obstack);
287 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
288 normal_insns = (rtx *) obstack_finish (&normal_obstack);
290 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
291 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
292 gen_proto (*insn_ptr);
294 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
295 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
296 gen_proto (*insn_ptr);
298 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
299 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
300 gen_nonproto (*insn_ptr);
302 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
303 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
304 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
305 gen_nonproto (*insn_ptr);
307 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
308 gen_nonproto (*insn_ptr);
310 printf ("#endif /* NO_MD_PROTOTYPES */\n");
312 fflush (stdout);
313 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
314 /* NOTREACHED */
315 return 0;