]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/genflags.c
Fix copyrights.
[thirdparty/gcc.git] / gcc / genflags.c
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,
5 1999, 2000 Free Software Foundation, Inc.
6
7 This file is part of GNU CC.
8
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.
13
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.
18
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. */
23
24
25 #include "hconfig.h"
26 #include "system.h"
27 #include "rtl.h"
28 #include "obstack.h"
29 #include "errors.h"
30
31 static struct obstack obstack;
32 struct obstack *rtl_obstack = &obstack;
33
34 #define obstack_chunk_alloc xmalloc
35 #define obstack_chunk_free free
36
37 /* Obstacks to remember normal, and call insns. */
38 static struct obstack call_obstack, normal_obstack;
39
40 /* Max size of names encountered. */
41 static int max_id_len;
42
43 /* Max operand encountered in a scan over some insn. */
44 static int max_opno;
45
46 static void max_operand_1 PARAMS ((rtx));
47 static int num_operands PARAMS ((rtx));
48 static void gen_proto PARAMS ((rtx));
49 static void gen_nonproto PARAMS ((rtx));
50 static void gen_insn PARAMS ((rtx));
51
52 /* Count the number of match_operand's found. */
53
54 static void
55 max_operand_1 (x)
56 rtx x;
57 {
58 register RTX_CODE code;
59 register int i;
60 register int len;
61 register const char *fmt;
62
63 if (x == 0)
64 return;
65
66 code = GET_CODE (x);
67
68 if (code == MATCH_OPERAND || code == MATCH_OPERATOR
69 || code == MATCH_PARALLEL)
70 max_opno = MAX (max_opno, XINT (x, 0));
71
72 fmt = GET_RTX_FORMAT (code);
73 len = GET_RTX_LENGTH (code);
74 for (i = 0; i < len; i++)
75 {
76 if (fmt[i] == 'e' || fmt[i] == 'u')
77 max_operand_1 (XEXP (x, i));
78 else if (fmt[i] == 'E')
79 {
80 int j;
81 for (j = 0; j < XVECLEN (x, i); j++)
82 max_operand_1 (XVECEXP (x, i, j));
83 }
84 }
85 }
86
87 static int
88 num_operands (insn)
89 rtx insn;
90 {
91 register int len = XVECLEN (insn, 1);
92 register int i;
93
94 max_opno = -1;
95
96 for (i = 0; i < len; i++)
97 max_operand_1 (XVECEXP (insn, 1, i));
98
99 return max_opno + 1;
100 }
101
102 /* Print out prototype information for a function. */
103
104 static void
105 gen_proto (insn)
106 rtx insn;
107 {
108 int num = num_operands (insn);
109 printf ("extern rtx gen_%-*s PARAMS ((", max_id_len, XSTR (insn, 0));
110
111 if (num == 0)
112 printf ("void");
113 else
114 {
115 while (num-- > 1)
116 printf ("rtx, ");
117
118 printf ("rtx");
119 }
120
121 printf ("));\n");
122 }
123
124 /* Print out a function declaration without a prototype. */
125
126 static void
127 gen_nonproto (insn)
128 rtx insn;
129 {
130 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
131 }
132
133 static void
134 gen_insn (insn)
135 rtx insn;
136 {
137 char *name = XSTR (insn, 0);
138 char *p;
139 struct obstack *obstack_ptr;
140 int len;
141
142 /* Don't mention instructions whose names are the null string
143 or begin with '*'. They are in the machine description just
144 to be recognized. */
145 if (name[0] == 0 || name[0] == '*')
146 return;
147
148 len = strlen (name);
149
150 if (len > max_id_len)
151 max_id_len = len;
152
153 printf ("#define HAVE_%s ", name);
154 if (strlen (XSTR (insn, 2)) == 0)
155 printf ("1\n");
156 else
157 {
158 /* Write the macro definition, putting \'s at the end of each line,
159 if more than one. */
160 printf ("(");
161 for (p = XSTR (insn, 2); *p; p++)
162 {
163 if (*p == '\n')
164 printf (" \\\n");
165 else
166 printf ("%c", *p);
167 }
168 printf (")\n");
169 }
170
171 /* Save the current insn, so that we can later put out appropriate
172 prototypes. At present, most md files have the wrong number of
173 arguments for the call insns (call, call_value, call_pop,
174 call_value_pop) ignoring the extra arguments that are passed for
175 some machines, so by default, turn off the prototype. */
176
177 obstack_ptr = (name[0] == 'c'
178 && (!strcmp (name, "call")
179 || !strcmp (name, "call_value")
180 || !strcmp (name, "call_pop")
181 || !strcmp (name, "call_value_pop")))
182 ? &call_obstack : &normal_obstack;
183
184 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
185 }
186 \f
187 PTR
188 xmalloc (size)
189 size_t size;
190 {
191 register PTR val = (PTR) malloc (size);
192
193 if (val == 0)
194 fatal ("virtual memory exhausted");
195
196 return val;
197 }
198
199 PTR
200 xrealloc (old, size)
201 PTR old;
202 size_t size;
203 {
204 register PTR ptr;
205 if (old)
206 ptr = (PTR) realloc (old, size);
207 else
208 ptr = (PTR) malloc (size);
209 if (!ptr)
210 fatal ("virtual memory exhausted");
211 return ptr;
212 }
213
214 extern int main PARAMS ((int, char **));
215
216 int
217 main (argc, argv)
218 int argc;
219 char **argv;
220 {
221 rtx desc;
222 rtx dummy;
223 rtx *call_insns;
224 rtx *normal_insns;
225 rtx *insn_ptr;
226 FILE *infile;
227 register int c;
228
229 progname = "genflags";
230 obstack_init (rtl_obstack);
231 obstack_init (&call_obstack);
232 obstack_init (&normal_obstack);
233
234 if (argc <= 1)
235 fatal ("No input file name.");
236
237 infile = fopen (argv[1], "r");
238 if (infile == 0)
239 {
240 perror (argv[1]);
241 return (FATAL_EXIT_CODE);
242 }
243 read_rtx_filename = argv[1];
244
245 printf ("/* Generated automatically by the program `genflags'\n\
246 from the machine description file `md'. */\n\n");
247
248 /* Read the machine description. */
249
250 while (1)
251 {
252 c = read_skip_spaces (infile);
253 if (c == EOF)
254 break;
255 ungetc (c, infile);
256
257 desc = read_rtx (infile);
258 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
259 gen_insn (desc);
260 }
261
262 /* Print out the prototypes now. */
263 dummy = (rtx) 0;
264 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
265 call_insns = (rtx *) obstack_finish (&call_obstack);
266
267 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
268 normal_insns = (rtx *) obstack_finish (&normal_obstack);
269
270 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
271 gen_proto (*insn_ptr);
272
273 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
274 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
275 gen_proto (*insn_ptr);
276
277 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
278 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
279 gen_nonproto (*insn_ptr);
280
281 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
282
283 fflush (stdout);
284 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
285 }
286
287 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
288 const char *
289 get_insn_name (code)
290 int code ATTRIBUTE_UNUSED;
291 {
292 return NULL;
293 }