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