(TARGET_FILE_SWITCHING): Define.
[official-gcc.git] / gcc / genflags.c
blobf8b39833f65aa3effc769d69872bf1073dadca1b
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 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 <stdio.h>
26 #include "hconfig.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 extern void free ();
37 extern rtx read_rtx ();
39 char *xmalloc ();
40 static void fatal ();
41 void fancy_abort ();
43 /* Names for patterns. Need to allow linking with print-rtl. */
44 char **insn_name_ptr;
46 /* Obstacks to remember normal, and call insns. */
47 static struct obstack call_obstack, normal_obstack;
49 /* Max size of names encountered. */
50 static int max_id_len;
52 /* Count the number of match_operand's found. */
54 static int
55 num_operands (x)
56 rtx x;
58 int count = 0;
59 int i, j;
60 enum rtx_code code = GET_CODE (x);
61 char *format_ptr = GET_RTX_FORMAT (code);
63 if (code == MATCH_OPERAND)
64 return 1;
66 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
67 count++;
69 for (i = 0; i < GET_RTX_LENGTH (code); i++)
71 switch (*format_ptr++)
73 case 'u':
74 case 'e':
75 count += num_operands (XEXP (x, i));
76 break;
78 case 'E':
79 if (XVEC (x, i) != NULL)
80 for (j = 0; j < XVECLEN (x, i); j++)
81 count += num_operands (XVECEXP (x, i, j));
83 break;
87 return count;
90 /* Print out prototype information for a function. */
92 static void
93 gen_proto (insn)
94 rtx insn;
96 int num = num_operands (insn);
97 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
99 if (num == 0)
100 printf ("void");
101 else
103 while (num-- > 1)
104 printf ("rtx, ");
106 printf ("rtx");
109 printf ("));\n");
112 /* Print out a function declaration without a prototype. */
114 static void
115 gen_nonproto (insn)
116 rtx insn;
118 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
121 static void
122 gen_insn (insn)
123 rtx insn;
125 char *name = XSTR (insn, 0);
126 char *p;
127 struct obstack *obstack_ptr;
128 int len;
130 /* Don't mention instructions whose names are the null string
131 or begin with '*'. They are in the machine description just
132 to be recognized. */
133 if (name[0] == 0 || name[0] == '*')
134 return;
136 len = strlen (name);
138 if (len > max_id_len)
139 max_id_len = len;
141 printf ("#define HAVE_%s ", name);
142 if (strlen (XSTR (insn, 2)) == 0)
143 printf ("1\n");
144 else
146 /* Write the macro definition, putting \'s at the end of each line,
147 if more than one. */
148 printf ("(");
149 for (p = XSTR (insn, 2); *p; p++)
151 if (*p == '\n')
152 printf (" \\\n");
153 else
154 printf ("%c", *p);
156 printf (")\n");
159 /* Save the current insn, so that we can later put out appropriate
160 prototypes. At present, most md files have the wrong number of
161 arguments for the call insns (call, call_value, call_pop,
162 call_value_pop) ignoring the extra arguments that are passed for
163 some machines, so by default, turn off the prototype. */
165 obstack_ptr = (name[0] == 'c'
166 && (!strcmp (name, "call")
167 || !strcmp (name, "call_value")
168 || !strcmp (name, "call_pop")
169 || !strcmp (name, "call_value_pop")))
170 ? &call_obstack : &normal_obstack;
172 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
175 char *
176 xmalloc (size)
177 unsigned size;
179 register char *val = (char *) malloc (size);
181 if (val == 0)
182 fatal ("virtual memory exhausted");
184 return val;
187 char *
188 xrealloc (ptr, size)
189 char *ptr;
190 unsigned size;
192 char *result = (char *) realloc (ptr, size);
193 if (!result)
194 fatal ("virtual memory exhausted");
195 return result;
198 static void
199 fatal (s, a1, a2)
200 char *s;
202 fprintf (stderr, "genflags: ");
203 fprintf (stderr, s, a1, a2);
204 fprintf (stderr, "\n");
205 exit (FATAL_EXIT_CODE);
208 /* More 'friendly' abort that prints the line and file.
209 config.h can #define abort fancy_abort if you like that sort of thing. */
211 void
212 fancy_abort ()
214 fatal ("Internal gcc abort.");
218 main (argc, argv)
219 int argc;
220 char **argv;
222 rtx desc;
223 rtx dummy;
224 rtx *call_insns;
225 rtx *normal_insns;
226 rtx *insn_ptr;
227 FILE *infile;
228 register int c;
230 obstack_init (rtl_obstack);
231 obstack_init (&call_obstack);
232 obstack_init (&normal_obstack);
234 if (argc <= 1)
235 fatal ("No input file name.");
237 infile = fopen (argv[1], "r");
238 if (infile == 0)
240 perror (argv[1]);
241 exit (FATAL_EXIT_CODE);
244 init_rtl ();
246 printf ("/* Generated automatically by the program `genflags'\n\
247 from the machine description file `md'. */\n\n");
249 /* Read the machine description. */
251 while (1)
253 c = read_skip_spaces (infile);
254 if (c == EOF)
255 break;
256 ungetc (c, infile);
258 desc = read_rtx (infile);
259 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
260 gen_insn (desc);
263 /* Print out the prototypes now. */
264 dummy = (rtx) 0;
265 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
266 call_insns = (rtx *) obstack_finish (&call_obstack);
268 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
269 normal_insns = (rtx *) obstack_finish (&normal_obstack);
271 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
272 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
273 gen_proto (*insn_ptr);
275 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
276 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
277 gen_proto (*insn_ptr);
279 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
280 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
281 gen_nonproto (*insn_ptr);
283 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
284 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
285 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
286 gen_nonproto (*insn_ptr);
288 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
289 gen_nonproto (*insn_ptr);
291 printf ("#endif /* NO_MD_PROTOTYPES */\n");
293 fflush (stdout);
294 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
295 /* NOTREACHED */
296 return 0;