Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / genflags.c
blobc6f602d1cd1f7305a0a6e1a0f6793ff048198657
1 /* Generate from machine description:
2 - some flags HAVE_... saying which simple standard instructions are
3 available for this machine.
4 Copyright (C) 1987, 1991, 1995, 1998 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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
24 #include "hconfig.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "obstack.h"
29 static struct obstack obstack;
30 struct obstack *rtl_obstack = &obstack;
32 #define obstack_chunk_alloc xmalloc
33 #define obstack_chunk_free free
35 extern rtx read_rtx ();
37 char *xmalloc ();
39 #ifdef HAVE_VPRINTF
40 void fatal PVPROTO((char *, ...));
41 #else
42 /* We must not provide any prototype here, even if ANSI C. */
43 void fatal PROTO(());
44 #endif
46 void fancy_abort ();
48 /* Names for patterns. Need to allow linking with print-rtl. */
49 char **insn_name_ptr;
51 /* Obstacks to remember normal, and call insns. */
52 static struct obstack call_obstack, normal_obstack;
54 /* Max size of names encountered. */
55 static int max_id_len;
57 /* Count the number of match_operand's found. */
59 static int
60 num_operands (x)
61 rtx x;
63 int count = 0;
64 int i, j;
65 enum rtx_code code = GET_CODE (x);
66 char *format_ptr = GET_RTX_FORMAT (code);
68 if (code == MATCH_OPERAND)
69 return 1;
71 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
72 count++;
74 for (i = 0; i < GET_RTX_LENGTH (code); i++)
76 switch (*format_ptr++)
78 case 'u':
79 case 'e':
80 count += num_operands (XEXP (x, i));
81 break;
83 case 'E':
84 if (XVEC (x, i) != NULL)
85 for (j = 0; j < XVECLEN (x, i); j++)
86 count += num_operands (XVECEXP (x, i, j));
88 break;
92 return count;
95 /* Print out prototype information for a function. */
97 static void
98 gen_proto (insn)
99 rtx insn;
101 int num = num_operands (insn);
102 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
104 if (num == 0)
105 printf ("void");
106 else
108 while (num-- > 1)
109 printf ("rtx, ");
111 printf ("rtx");
114 printf ("));\n");
117 /* Print out a function declaration without a prototype. */
119 static void
120 gen_nonproto (insn)
121 rtx insn;
123 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
126 static void
127 gen_insn (insn)
128 rtx insn;
130 char *name = XSTR (insn, 0);
131 char *p;
132 struct obstack *obstack_ptr;
133 int len;
135 /* Don't mention instructions whose names are the null string
136 or begin with '*'. They are in the machine description just
137 to be recognized. */
138 if (name[0] == 0 || name[0] == '*')
139 return;
141 len = strlen (name);
143 if (len > max_id_len)
144 max_id_len = len;
146 printf ("#define HAVE_%s ", name);
147 if (strlen (XSTR (insn, 2)) == 0)
148 printf ("1\n");
149 else
151 /* Write the macro definition, putting \'s at the end of each line,
152 if more than one. */
153 printf ("(");
154 for (p = XSTR (insn, 2); *p; p++)
156 if (*p == '\n')
157 printf (" \\\n");
158 else
159 printf ("%c", *p);
161 printf (")\n");
164 /* Save the current insn, so that we can later put out appropriate
165 prototypes. At present, most md files have the wrong number of
166 arguments for the call insns (call, call_value, call_pop,
167 call_value_pop) ignoring the extra arguments that are passed for
168 some machines, so by default, turn off the prototype. */
170 obstack_ptr = (name[0] == 'c'
171 && (!strcmp (name, "call")
172 || !strcmp (name, "call_value")
173 || !strcmp (name, "call_pop")
174 || !strcmp (name, "call_value_pop")))
175 ? &call_obstack : &normal_obstack;
177 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
180 char *
181 xmalloc (size)
182 unsigned size;
184 register char *val = (char *) malloc (size);
186 if (val == 0)
187 fatal ("virtual memory exhausted");
189 return val;
192 char *
193 xrealloc (ptr, size)
194 char *ptr;
195 unsigned size;
197 char *result = (char *) realloc (ptr, size);
198 if (!result)
199 fatal ("virtual memory exhausted");
200 return result;
204 #ifdef HAVE_VPRINTF
205 void
206 fatal VPROTO((char *s, ...))
208 #ifndef ANSI_PROTOTYPES
209 char *s;
210 #endif
211 va_list ap;
213 VA_START (ap, s);
215 #ifndef ANSI_PROTOTYPES
216 s = va_arg (ap, char *);
217 #endif
219 fprintf (stderr, "genflags: ");
220 vfprintf (stderr, s, ap);
221 va_end (ap);
222 fprintf (stderr, "\n");
223 exit (FATAL_EXIT_CODE);
225 #else /* not HAVE_VPRINTF */
227 void
228 fatal (s, a1, a2)
229 char *s;
231 fprintf (stderr, "genflags: ");
232 fprintf (stderr, s, a1, a2);
233 fprintf (stderr, "\n");
234 exit (FATAL_EXIT_CODE);
236 #endif /* not HAVE_VPRINTF */
238 /* More 'friendly' abort that prints the line and file.
239 config.h can #define abort fancy_abort if you like that sort of thing. */
241 void
242 fancy_abort ()
244 fatal ("Internal gcc abort.");
248 main (argc, argv)
249 int argc;
250 char **argv;
252 rtx desc;
253 rtx dummy;
254 rtx *call_insns;
255 rtx *normal_insns;
256 rtx *insn_ptr;
257 FILE *infile;
258 register int c;
260 obstack_init (rtl_obstack);
261 obstack_init (&call_obstack);
262 obstack_init (&normal_obstack);
264 if (argc <= 1)
265 fatal ("No input file name.");
267 infile = fopen (argv[1], "r");
268 if (infile == 0)
270 perror (argv[1]);
271 exit (FATAL_EXIT_CODE);
274 init_rtl ();
276 printf ("/* Generated automatically by the program `genflags'\n\
277 from the machine description file `md'. */\n\n");
279 /* Read the machine description. */
281 while (1)
283 c = read_skip_spaces (infile);
284 if (c == EOF)
285 break;
286 ungetc (c, infile);
288 desc = read_rtx (infile);
289 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
290 gen_insn (desc);
293 /* Print out the prototypes now. */
294 dummy = (rtx) 0;
295 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
296 call_insns = (rtx *) obstack_finish (&call_obstack);
298 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
299 normal_insns = (rtx *) obstack_finish (&normal_obstack);
301 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
302 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
303 gen_proto (*insn_ptr);
305 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
306 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
307 gen_proto (*insn_ptr);
309 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
310 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
311 gen_nonproto (*insn_ptr);
313 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
314 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
315 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
316 gen_nonproto (*insn_ptr);
318 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
319 gen_nonproto (*insn_ptr);
321 printf ("#endif /* NO_MD_PROTOTYPES */\n");
323 fflush (stdout);
324 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
325 /* NOTREACHED */
326 return 0;