Daily bump.
[official-gcc.git] / gcc / genflags.c
blob636aafeed57320801685c8433e7d13e844f1ee9b
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, 1999 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 #include "system.h"
27 #include "rtl.h"
28 #include "obstack.h"
30 static struct obstack obstack;
31 struct obstack *rtl_obstack = &obstack;
33 #define obstack_chunk_alloc xmalloc
34 #define obstack_chunk_free free
36 void fatal PVPROTO ((const char *, ...))
37 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
38 void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
40 /* Names for patterns. Need to allow linking with print-rtl. */
41 char **insn_name_ptr;
43 /* Obstacks to remember normal, and call insns. */
44 static struct obstack call_obstack, normal_obstack;
46 /* Max size of names encountered. */
47 static int max_id_len;
49 static int num_operands PROTO((rtx));
50 static void gen_proto PROTO((rtx));
51 static void gen_nonproto PROTO((rtx));
52 static void gen_insn PROTO((rtx));
55 /* Count the number of match_operand's found. */
57 static int
58 num_operands (x)
59 rtx x;
61 int count = 0;
62 int i, j;
63 enum rtx_code code = GET_CODE (x);
64 char *format_ptr = GET_RTX_FORMAT (code);
66 if (code == MATCH_OPERAND)
67 return 1;
69 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
70 count++;
72 for (i = 0; i < GET_RTX_LENGTH (code); i++)
74 switch (*format_ptr++)
76 case 'u':
77 case 'e':
78 count += num_operands (XEXP (x, i));
79 break;
81 case 'E':
82 if (XVEC (x, i) != NULL)
83 for (j = 0; j < XVECLEN (x, i); j++)
84 count += num_operands (XVECEXP (x, i, j));
86 break;
90 return count;
93 /* Print out prototype information for a function. */
95 static void
96 gen_proto (insn)
97 rtx insn;
99 int num = num_operands (insn);
100 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
102 if (num == 0)
103 printf ("void");
104 else
106 while (num-- > 1)
107 printf ("rtx, ");
109 printf ("rtx");
112 printf ("));\n");
115 /* Print out a function declaration without a prototype. */
117 static void
118 gen_nonproto (insn)
119 rtx insn;
121 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
124 static void
125 gen_insn (insn)
126 rtx insn;
128 char *name = XSTR (insn, 0);
129 char *p;
130 struct obstack *obstack_ptr;
131 int len;
133 /* Don't mention instructions whose names are the null string
134 or begin with '*'. They are in the machine description just
135 to be recognized. */
136 if (name[0] == 0 || name[0] == '*')
137 return;
139 len = strlen (name);
141 if (len > max_id_len)
142 max_id_len = len;
144 printf ("#define HAVE_%s ", name);
145 if (strlen (XSTR (insn, 2)) == 0)
146 printf ("1\n");
147 else
149 /* Write the macro definition, putting \'s at the end of each line,
150 if more than one. */
151 printf ("(");
152 for (p = XSTR (insn, 2); *p; p++)
154 if (*p == '\n')
155 printf (" \\\n");
156 else
157 printf ("%c", *p);
159 printf (")\n");
162 /* Save the current insn, so that we can later put out appropriate
163 prototypes. At present, most md files have the wrong number of
164 arguments for the call insns (call, call_value, call_pop,
165 call_value_pop) ignoring the extra arguments that are passed for
166 some machines, so by default, turn off the prototype. */
168 obstack_ptr = (name[0] == 'c'
169 && (!strcmp (name, "call")
170 || !strcmp (name, "call_value")
171 || !strcmp (name, "call_pop")
172 || !strcmp (name, "call_value_pop")))
173 ? &call_obstack : &normal_obstack;
175 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
179 xmalloc (size)
180 size_t size;
182 register PTR val = (PTR) malloc (size);
184 if (val == 0)
185 fatal ("virtual memory exhausted");
187 return val;
191 xrealloc (old, size)
192 PTR old;
193 size_t size;
195 register PTR ptr;
196 if (old)
197 ptr = (PTR) realloc (old, size);
198 else
199 ptr = (PTR) malloc (size);
200 if (!ptr)
201 fatal ("virtual memory exhausted");
202 return ptr;
205 void
206 fatal VPROTO ((const char *format, ...))
208 #ifndef ANSI_PROTOTYPES
209 const char *format;
210 #endif
211 va_list ap;
213 VA_START (ap, format);
215 #ifndef ANSI_PROTOTYPES
216 format = va_arg (ap, const char *);
217 #endif
219 fprintf (stderr, "genflags: ");
220 vfprintf (stderr, format, ap);
221 va_end (ap);
222 fprintf (stderr, "\n");
223 exit (FATAL_EXIT_CODE);
226 /* More 'friendly' abort that prints the line and file.
227 config.h can #define abort fancy_abort if you like that sort of thing. */
229 void
230 fancy_abort ()
232 fatal ("Internal gcc abort.");
236 main (argc, argv)
237 int argc;
238 char **argv;
240 rtx desc;
241 rtx dummy;
242 rtx *call_insns;
243 rtx *normal_insns;
244 rtx *insn_ptr;
245 FILE *infile;
246 register int c;
248 obstack_init (rtl_obstack);
249 obstack_init (&call_obstack);
250 obstack_init (&normal_obstack);
252 if (argc <= 1)
253 fatal ("No input file name.");
255 infile = fopen (argv[1], "r");
256 if (infile == 0)
258 perror (argv[1]);
259 exit (FATAL_EXIT_CODE);
262 init_rtl ();
264 printf ("/* Generated automatically by the program `genflags'\n\
265 from the machine description file `md'. */\n\n");
267 /* Read the machine description. */
269 while (1)
271 c = read_skip_spaces (infile);
272 if (c == EOF)
273 break;
274 ungetc (c, infile);
276 desc = read_rtx (infile);
277 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
278 gen_insn (desc);
281 /* Print out the prototypes now. */
282 dummy = (rtx) 0;
283 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
284 call_insns = (rtx *) obstack_finish (&call_obstack);
286 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
287 normal_insns = (rtx *) obstack_finish (&normal_obstack);
289 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
290 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
291 gen_proto (*insn_ptr);
293 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
294 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
295 gen_proto (*insn_ptr);
297 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
298 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
299 gen_nonproto (*insn_ptr);
301 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
302 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
303 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
304 gen_nonproto (*insn_ptr);
306 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
307 gen_nonproto (*insn_ptr);
309 printf ("#endif /* NO_MD_PROTOTYPES */\n");
311 fflush (stdout);
312 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
313 /* NOTREACHED */
314 return 0;