]> gcc.gnu.org Git - gcc.git/blame - gcc/genflags.c
* c-typeck.c (pop_init_level): Simplify.
[gcc.git] / gcc / genflags.c
CommitLineData
41299f41 1/* Generate from machine description:
41299f41
TW
2 - some flags HAVE_... saying which simple standard instructions are
3 available for this machine.
d050d723 4 Copyright (C) 1987, 1991, 1995, 1998,
d9221e01 5 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
41299f41 6
1322177d 7This file is part of GCC.
41299f41 8
1322177d
LB
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 2, or (at your option) any later
12version.
41299f41 13
1322177d
LB
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
41299f41
TW
18
19You should have received a copy of the GNU General Public License
1322177d 20along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
21Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2202110-1301, USA. */
41299f41
TW
23
24
4977bab6 25#include "bconfig.h"
0b93b64e 26#include "system.h"
4977bab6
ZW
27#include "coretypes.h"
28#include "tm.h"
41299f41
TW
29#include "rtl.h"
30#include "obstack.h"
f8b6598e 31#include "errors.h"
c88c0d42 32#include "gensupport.h"
41299f41 33
f45c9d95
ZW
34/* Obstack to remember insns with. */
35static struct obstack obstack;
f837a861
MM
36
37/* Max size of names encountered. */
38static int max_id_len;
39
706b0f60
ZW
40/* Max operand encountered in a scan over some insn. */
41static int max_opno;
56c0e996 42
3d7aafde
AJ
43static void max_operand_1 (rtx);
44static int num_operands (rtx);
45static void gen_proto (rtx);
46static void gen_macro (const char *, int, int);
47static void gen_insn (rtx);
56c0e996 48
f837a861 49/* Count the number of match_operand's found. */
0f41302f 50
706b0f60 51static void
3d7aafde 52max_operand_1 (rtx x)
f837a861 53{
b3694847
SS
54 RTX_CODE code;
55 int i;
56 int len;
57 const char *fmt;
f837a861 58
706b0f60
ZW
59 if (x == 0)
60 return;
f837a861 61
706b0f60 62 code = GET_CODE (x);
f837a861 63
706b0f60
ZW
64 if (code == MATCH_OPERAND || code == MATCH_OPERATOR
65 || code == MATCH_PARALLEL)
66 max_opno = MAX (max_opno, XINT (x, 0));
67
68 fmt = GET_RTX_FORMAT (code);
69 len = GET_RTX_LENGTH (code);
70 for (i = 0; i < len; i++)
f837a861 71 {
706b0f60
ZW
72 if (fmt[i] == 'e' || fmt[i] == 'u')
73 max_operand_1 (XEXP (x, i));
74 else if (fmt[i] == 'E')
f837a861 75 {
706b0f60
ZW
76 int j;
77 for (j = 0; j < XVECLEN (x, i); j++)
78 max_operand_1 (XVECEXP (x, i, j));
f837a861
MM
79 }
80 }
706b0f60 81}
f837a861 82
706b0f60 83static int
3d7aafde 84num_operands (rtx insn)
706b0f60 85{
b3694847
SS
86 int len = XVECLEN (insn, 1);
87 int i;
706b0f60
ZW
88
89 max_opno = -1;
90
91 for (i = 0; i < len; i++)
92 max_operand_1 (XVECEXP (insn, 1, i));
93
94 return max_opno + 1;
f837a861
MM
95}
96
f45c9d95
ZW
97/* Print out a wrapper macro for a function which corrects the number
98 of arguments it takes. Any missing arguments are assumed to be at
99 the end. */
100static void
3d7aafde 101gen_macro (const char *name, int real, int expect)
f45c9d95
ZW
102{
103 int i;
104
b2d59f6f
NS
105 gcc_assert (real <= expect);
106 gcc_assert (real);
f45c9d95
ZW
107
108 /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
109 fputs ("#define GEN_", stdout);
110 for (i = 0; name[i]; i++)
111 putchar (TOUPPER (name[i]));
112
113 putchar('(');
114 for (i = 0; i < expect - 1; i++)
115 printf ("%c, ", i + 'A');
116 printf ("%c) gen_%s (", i + 'A', name);
117
118 for (i = 0; i < real - 1; i++)
119 printf ("(%c), ", i + 'A');
120 printf ("(%c))\n", i + 'A');
121}
122
2199e5fa
ZW
123/* Print out prototype information for a generator function. If the
124 insn pattern has been elided, print out a dummy generator that
125 does nothing. */
0f41302f 126
f837a861 127static void
3d7aafde 128gen_proto (rtx insn)
f837a861
MM
129{
130 int num = num_operands (insn);
2199e5fa 131 int i;
f45c9d95 132 const char *name = XSTR (insn, 0);
2199e5fa 133 int truth = maybe_eval_c_test (XSTR (insn, 2));
f45c9d95
ZW
134
135 /* Many md files don't refer to the last two operands passed to the
136 call patterns. This means their generator functions will be two
137 arguments too short. Instead of changing every md file to touch
138 those operands, we wrap the prototypes in macros that take the
139 correct number of arguments. */
140 if (name[0] == 'c' || name[0] == 's')
141 {
142 if (!strcmp (name, "call")
143 || !strcmp (name, "call_pop")
144 || !strcmp (name, "sibcall")
145 || !strcmp (name, "sibcall_pop"))
146 gen_macro (name, num, 4);
147 else if (!strcmp (name, "call_value")
148 || !strcmp (name, "call_value_pop")
149 || !strcmp (name, "sibcall_value")
150 || !strcmp (name, "sibcall_value_pop"))
151 gen_macro (name, num, 5);
152 }
153
2199e5fa 154 if (truth != 0)
3d7aafde 155 printf ("extern rtx gen_%-*s (", max_id_len, name);
2199e5fa 156 else
3d7aafde 157 printf ("static inline rtx gen_%-*s (", max_id_len, name);
f837a861
MM
158
159 if (num == 0)
2199e5fa 160 fputs ("void", stdout);
f837a861
MM
161 else
162 {
2199e5fa
ZW
163 for (i = 1; i < num; i++)
164 fputs ("rtx, ", stdout);
3d7aafde 165
2199e5fa 166 fputs ("rtx", stdout);
f837a861
MM
167 }
168
3d7aafde 169 puts (");");
2199e5fa
ZW
170
171 /* Some back ends want to take the address of generator functions,
172 so we cannot simply use #define for these dummy definitions. */
173 if (truth == 0)
174 {
175 printf ("static inline rtx\ngen_%s", name);
176 if (num > 0)
177 {
178 putchar ('(');
179 for (i = 0; i < num-1; i++)
e18476eb
BI
180 printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
181 printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
2199e5fa
ZW
182 }
183 else
5671bf27 184 puts ("(void)");
2199e5fa
ZW
185 puts ("{\n return 0;\n}");
186 }
f837a861 187
f837a861
MM
188}
189
41299f41 190static void
3d7aafde 191gen_insn (rtx insn)
41299f41 192{
3cce094d
KG
193 const char *name = XSTR (insn, 0);
194 const char *p;
f837a861 195 int len;
2199e5fa 196 int truth = maybe_eval_c_test (XSTR (insn, 2));
41299f41 197
6b6ca844
RK
198 /* Don't mention instructions whose names are the null string
199 or begin with '*'. They are in the machine description just
200 to be recognized. */
201 if (name[0] == 0 || name[0] == '*')
41299f41
TW
202 return;
203
6b6ca844
RK
204 len = strlen (name);
205
f837a861
MM
206 if (len > max_id_len)
207 max_id_len = len;
208
2199e5fa 209 if (truth == 0)
e0a21ab9 210 /* Emit nothing. */;
2199e5fa
ZW
211 else if (truth == 1)
212 printf ("#define HAVE_%s 1\n", name);
41299f41
TW
213 else
214 {
215 /* Write the macro definition, putting \'s at the end of each line,
216 if more than one. */
2199e5fa 217 printf ("#define HAVE_%s (", name);
41299f41
TW
218 for (p = XSTR (insn, 2); *p; p++)
219 {
6b8b9d7b 220 if (IS_VSPACE (*p))
2199e5fa 221 fputs (" \\\n", stdout);
41299f41 222 else
2199e5fa 223 putchar (*p);
41299f41 224 }
2199e5fa 225 fputs (")\n", stdout);
41299f41 226 }
6610a1b0 227
f45c9d95 228 obstack_grow (&obstack, &insn, sizeof (rtx));
41299f41 229}
41299f41 230
41299f41 231int
3d7aafde 232main (int argc, char **argv)
41299f41
TW
233{
234 rtx desc;
f837a861 235 rtx dummy;
f45c9d95 236 rtx *insns;
f837a861 237 rtx *insn_ptr;
41299f41 238
f8b6598e 239 progname = "genflags";
f45c9d95 240 obstack_init (&obstack);
41299f41 241
2199e5fa
ZW
242 /* We need to see all the possibilities. Elided insns may have
243 direct calls to their generators in C code. */
244 insn_elision = 0;
245
04d8aa70 246 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 247 return (FATAL_EXIT_CODE);
3d7aafde 248
0313e85b
ZW
249 puts ("/* Generated automatically by the program `genflags'");
250 puts (" from the machine description file `md'. */\n");
251 puts ("#ifndef GCC_INSN_FLAGS_H");
252 puts ("#define GCC_INSN_FLAGS_H\n");
41299f41
TW
253
254 /* Read the machine description. */
255
256 while (1)
257 {
c88c0d42 258 int line_no, insn_code_number = 0;
41299f41 259
c88c0d42
CP
260 desc = read_md_rtx (&line_no, &insn_code_number);
261 if (desc == NULL)
262 break;
41299f41
TW
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;
f45c9d95 269 obstack_grow (&obstack, &dummy, sizeof (rtx));
7973fd2a 270 insns = XOBFINISH (&obstack, rtx *);
f837a861 271
f45c9d95 272 for (insn_ptr = insns; *insn_ptr; insn_ptr++)
f837a861
MM
273 gen_proto (*insn_ptr);
274
0313e85b
ZW
275 puts("\n#endif /* GCC_INSN_FLAGS_H */");
276
277 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
278 return FATAL_EXIT_CODE;
279
280 return SUCCESS_EXIT_CODE;
41299f41 281}
This page took 2.72087 seconds and 5 git commands to generate.