]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genflags.c
c-common.c: Include <stdlib.h> and <string.h>/<strings.h>.
[thirdparty/gcc.git] / gcc / genflags.c
CommitLineData
41299f41
TW
1/* Generate from machine description:
2
3 - some flags HAVE_... saying which simple standard instructions are
4 available for this machine.
6b6ca844 5 Copyright (C) 1987, 1991, 1995 Free Software Foundation, Inc.
41299f41
TW
6
7This file is part of GNU CC.
8
9GNU CC is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU CC is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU CC; see the file COPYING. If not, write to
a35311b0
RK
21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
41299f41
TW
23
24
25#include <stdio.h>
20f92396 26#include "hconfig.h"
41299f41
TW
27#include "rtl.h"
28#include "obstack.h"
29
ccd043a9
RL
30#ifdef HAVE_STDLIB_H
31#include <stdlib.h>
32#endif
33
41299f41
TW
34static struct obstack obstack;
35struct obstack *rtl_obstack = &obstack;
36
37#define obstack_chunk_alloc xmalloc
38#define obstack_chunk_free free
39
40extern void free ();
13884488 41extern rtx read_rtx ();
41299f41
TW
42
43char *xmalloc ();
44static void fatal ();
45void fancy_abort ();
46
f837a861
MM
47/* Names for patterns. Need to allow linking with print-rtl. */
48char **insn_name_ptr;
49
50/* Obstacks to remember normal, and call insns. */
51static struct obstack call_obstack, normal_obstack;
52
53/* Max size of names encountered. */
54static int max_id_len;
55
56/* Count the number of match_operand's found. */
0f41302f 57
f837a861
MM
58static int
59num_operands (x)
60 rtx x;
61{
62 int count = 0;
63 int i, j;
64 enum rtx_code code = GET_CODE (x);
65 char *format_ptr = GET_RTX_FORMAT (code);
66
67 if (code == MATCH_OPERAND)
68 return 1;
69
c7d26bc1 70 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
f837a861
MM
71 count++;
72
73 for (i = 0; i < GET_RTX_LENGTH (code); i++)
74 {
75 switch (*format_ptr++)
76 {
77 case 'u':
78 case 'e':
79 count += num_operands (XEXP (x, i));
80 break;
81
82 case 'E':
83 if (XVEC (x, i) != NULL)
84 for (j = 0; j < XVECLEN (x, i); j++)
85 count += num_operands (XVECEXP (x, i, j));
86
87 break;
88 }
89 }
90
91 return count;
92}
93
94/* Print out prototype information for a function. */
0f41302f 95
f837a861
MM
96static void
97gen_proto (insn)
98 rtx insn;
99{
100 int num = num_operands (insn);
101 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
102
103 if (num == 0)
104 printf ("void");
105 else
106 {
107 while (num-- > 1)
108 printf ("rtx, ");
109
110 printf ("rtx");
111 }
112
113 printf ("));\n");
114}
115
116/* Print out a function declaration without a prototype. */
0f41302f 117
f837a861
MM
118static void
119gen_nonproto (insn)
120 rtx insn;
121{
122 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
123}
124
41299f41
TW
125static void
126gen_insn (insn)
127 rtx insn;
128{
f837a861 129 char *name = XSTR (insn, 0);
41299f41 130 char *p;
f837a861
MM
131 struct obstack *obstack_ptr;
132 int len;
41299f41 133
6b6ca844
RK
134 /* Don't mention instructions whose names are the null string
135 or begin with '*'. They are in the machine description just
136 to be recognized. */
137 if (name[0] == 0 || name[0] == '*')
41299f41
TW
138 return;
139
6b6ca844
RK
140 len = strlen (name);
141
f837a861
MM
142 if (len > max_id_len)
143 max_id_len = len;
144
145 printf ("#define HAVE_%s ", name);
41299f41
TW
146 if (strlen (XSTR (insn, 2)) == 0)
147 printf ("1\n");
148 else
149 {
150 /* Write the macro definition, putting \'s at the end of each line,
151 if more than one. */
152 printf ("(");
153 for (p = XSTR (insn, 2); *p; p++)
154 {
155 if (*p == '\n')
156 printf (" \\\n");
157 else
158 printf ("%c", *p);
159 }
160 printf (")\n");
161 }
6610a1b0 162
f837a861
MM
163 /* Save the current insn, so that we can later put out appropriate
164 prototypes. At present, most md files have the wrong number of
6610a1b0
MM
165 arguments for the call insns (call, call_value, call_pop,
166 call_value_pop) ignoring the extra arguments that are passed for
167 some machines, so by default, turn off the prototype. */
168
169 obstack_ptr = (name[0] == 'c'
170 && (!strcmp (name, "call")
171 || !strcmp (name, "call_value")
172 || !strcmp (name, "call_pop")
173 || !strcmp (name, "call_value_pop")))
f837a861
MM
174 ? &call_obstack : &normal_obstack;
175
176 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
41299f41
TW
177}
178\f
179char *
180xmalloc (size)
181 unsigned size;
182{
183 register char *val = (char *) malloc (size);
184
185 if (val == 0)
186 fatal ("virtual memory exhausted");
187
188 return val;
189}
190
191char *
192xrealloc (ptr, size)
193 char *ptr;
194 unsigned size;
195{
196 char *result = (char *) realloc (ptr, size);
197 if (!result)
198 fatal ("virtual memory exhausted");
199 return result;
200}
201
202static void
203fatal (s, a1, a2)
204 char *s;
205{
206 fprintf (stderr, "genflags: ");
207 fprintf (stderr, s, a1, a2);
208 fprintf (stderr, "\n");
209 exit (FATAL_EXIT_CODE);
210}
211
212/* More 'friendly' abort that prints the line and file.
213 config.h can #define abort fancy_abort if you like that sort of thing. */
214
215void
216fancy_abort ()
217{
218 fatal ("Internal gcc abort.");
219}
220\f
221int
222main (argc, argv)
223 int argc;
224 char **argv;
225{
226 rtx desc;
f837a861
MM
227 rtx dummy;
228 rtx *call_insns;
229 rtx *normal_insns;
230 rtx *insn_ptr;
41299f41 231 FILE *infile;
41299f41
TW
232 register int c;
233
234 obstack_init (rtl_obstack);
f837a861
MM
235 obstack_init (&call_obstack);
236 obstack_init (&normal_obstack);
41299f41
TW
237
238 if (argc <= 1)
239 fatal ("No input file name.");
240
241 infile = fopen (argv[1], "r");
242 if (infile == 0)
243 {
244 perror (argv[1]);
245 exit (FATAL_EXIT_CODE);
246 }
247
248 init_rtl ();
249
250 printf ("/* Generated automatically by the program `genflags'\n\
251from the machine description file `md'. */\n\n");
252
253 /* Read the machine description. */
254
255 while (1)
256 {
257 c = read_skip_spaces (infile);
258 if (c == EOF)
259 break;
260 ungetc (c, infile);
261
262 desc = read_rtx (infile);
263 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
264 gen_insn (desc);
265 }
266
f837a861 267 /* Print out the prototypes now. */
0f41302f 268 dummy = (rtx) 0;
f837a861
MM
269 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
270 call_insns = (rtx *) obstack_finish (&call_obstack);
271
272 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
273 normal_insns = (rtx *) obstack_finish (&normal_obstack);
274
275 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
276 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
277 gen_proto (*insn_ptr);
278
279 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
280 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
281 gen_proto (*insn_ptr);
282
283 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
284 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
285 gen_nonproto (*insn_ptr);
286
287 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
288 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
289 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
290 gen_nonproto (*insn_ptr);
291
292 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
293 gen_nonproto (*insn_ptr);
294
295 printf ("#endif /* NO_MD_PROTOTYPES */\n");
296
41299f41
TW
297 fflush (stdout);
298 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
299 /* NOTREACHED */
300 return 0;
301}