]> gcc.gnu.org Git - gcc.git/blame - gcc/genflags.c
rtl.c: Define CONST_DOUBLE_FORMAT to the appropriate format for a CONST_DOUBLE...
[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.
34627ce6 5 Copyright (C) 1987, 1991, 1995, 1998, 1999 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
20f92396 25#include "hconfig.h"
0b93b64e 26#include "system.h"
41299f41
TW
27#include "rtl.h"
28#include "obstack.h"
f8b6598e 29#include "errors.h"
41299f41
TW
30
31static struct obstack obstack;
32struct obstack *rtl_obstack = &obstack;
33
34#define obstack_chunk_alloc xmalloc
35#define obstack_chunk_free free
36
f837a861
MM
37/* Names for patterns. Need to allow linking with print-rtl. */
38char **insn_name_ptr;
39
40/* Obstacks to remember normal, and call insns. */
41static struct obstack call_obstack, normal_obstack;
42
43/* Max size of names encountered. */
44static int max_id_len;
45
56c0e996
BS
46static int num_operands PROTO((rtx));
47static void gen_proto PROTO((rtx));
48static void gen_nonproto PROTO((rtx));
49static void gen_insn PROTO((rtx));
50
51
f837a861 52/* Count the number of match_operand's found. */
0f41302f 53
f837a861
MM
54static int
55num_operands (x)
56 rtx x;
57{
58 int count = 0;
59 int i, j;
60 enum rtx_code code = GET_CODE (x);
6f7d635c 61 const char *format_ptr = GET_RTX_FORMAT (code);
f837a861
MM
62
63 if (code == MATCH_OPERAND)
64 return 1;
65
c7d26bc1 66 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
f837a861
MM
67 count++;
68
69 for (i = 0; i < GET_RTX_LENGTH (code); i++)
70 {
71 switch (*format_ptr++)
72 {
73 case 'u':
74 case 'e':
75 count += num_operands (XEXP (x, i));
76 break;
77
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));
82
83 break;
84 }
85 }
86
87 return count;
88}
89
90/* Print out prototype information for a function. */
0f41302f 91
f837a861
MM
92static void
93gen_proto (insn)
94 rtx insn;
95{
96 int num = num_operands (insn);
97 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
98
99 if (num == 0)
100 printf ("void");
101 else
102 {
103 while (num-- > 1)
104 printf ("rtx, ");
105
106 printf ("rtx");
107 }
108
109 printf ("));\n");
110}
111
112/* Print out a function declaration without a prototype. */
0f41302f 113
f837a861
MM
114static void
115gen_nonproto (insn)
116 rtx insn;
117{
118 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
119}
120
41299f41
TW
121static void
122gen_insn (insn)
123 rtx insn;
124{
f837a861 125 char *name = XSTR (insn, 0);
41299f41 126 char *p;
f837a861
MM
127 struct obstack *obstack_ptr;
128 int len;
41299f41 129
6b6ca844
RK
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] == '*')
41299f41
TW
134 return;
135
6b6ca844
RK
136 len = strlen (name);
137
f837a861
MM
138 if (len > max_id_len)
139 max_id_len = len;
140
141 printf ("#define HAVE_%s ", name);
41299f41
TW
142 if (strlen (XSTR (insn, 2)) == 0)
143 printf ("1\n");
144 else
145 {
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++)
150 {
151 if (*p == '\n')
152 printf (" \\\n");
153 else
154 printf ("%c", *p);
155 }
156 printf (")\n");
157 }
6610a1b0 158
f837a861
MM
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
6610a1b0
MM
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. */
164
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")))
f837a861
MM
170 ? &call_obstack : &normal_obstack;
171
172 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
41299f41
TW
173}
174\f
2778b98d 175PTR
41299f41 176xmalloc (size)
2778b98d 177 size_t size;
41299f41 178{
2778b98d 179 register PTR val = (PTR) malloc (size);
41299f41
TW
180
181 if (val == 0)
182 fatal ("virtual memory exhausted");
183
184 return val;
185}
186
2778b98d 187PTR
470b68c0
RH
188xrealloc (old, size)
189 PTR old;
2778b98d 190 size_t size;
41299f41 191{
470b68c0 192 register PTR ptr;
09d83d25 193 if (old)
470b68c0
RH
194 ptr = (PTR) realloc (old, size);
195 else
196 ptr = (PTR) malloc (size);
197 if (!ptr)
41299f41 198 fatal ("virtual memory exhausted");
470b68c0 199 return ptr;
41299f41
TW
200}
201
41299f41
TW
202int
203main (argc, argv)
204 int argc;
205 char **argv;
206{
207 rtx desc;
f837a861
MM
208 rtx dummy;
209 rtx *call_insns;
210 rtx *normal_insns;
211 rtx *insn_ptr;
41299f41 212 FILE *infile;
41299f41
TW
213 register int c;
214
f8b6598e 215 progname = "genflags";
41299f41 216 obstack_init (rtl_obstack);
f837a861
MM
217 obstack_init (&call_obstack);
218 obstack_init (&normal_obstack);
41299f41
TW
219
220 if (argc <= 1)
221 fatal ("No input file name.");
222
223 infile = fopen (argv[1], "r");
224 if (infile == 0)
225 {
226 perror (argv[1]);
227 exit (FATAL_EXIT_CODE);
228 }
229
41299f41
TW
230 printf ("/* Generated automatically by the program `genflags'\n\
231from the machine description file `md'. */\n\n");
232
233 /* Read the machine description. */
234
235 while (1)
236 {
237 c = read_skip_spaces (infile);
238 if (c == EOF)
239 break;
240 ungetc (c, infile);
241
242 desc = read_rtx (infile);
243 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
244 gen_insn (desc);
245 }
246
f837a861 247 /* Print out the prototypes now. */
0f41302f 248 dummy = (rtx) 0;
f837a861
MM
249 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
250 call_insns = (rtx *) obstack_finish (&call_obstack);
251
252 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
253 normal_insns = (rtx *) obstack_finish (&normal_obstack);
254
255 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
256 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
257 gen_proto (*insn_ptr);
258
259 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
260 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
261 gen_proto (*insn_ptr);
262
263 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
264 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
265 gen_nonproto (*insn_ptr);
266
267 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
268 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
269 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
270 gen_nonproto (*insn_ptr);
271
272 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
273 gen_nonproto (*insn_ptr);
274
275 printf ("#endif /* NO_MD_PROTOTYPES */\n");
276
41299f41
TW
277 fflush (stdout);
278 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
279 /* NOTREACHED */
280 return 0;
281}
This page took 0.742686 seconds and 5 git commands to generate.