1c3d31fe1Smrg /* Generate from machine description:
2c3d31fe1Smrg - some flags HAVE_... saying which simple standard instructions are
3c3d31fe1Smrg available for this machine.
4*dd083157Smrg Copyright (C) 1987-2020 Free Software Foundation, Inc.
5c3d31fe1Smrg
6c3d31fe1Smrg This file is part of GCC.
7c3d31fe1Smrg
8c3d31fe1Smrg GCC is free software; you can redistribute it and/or modify it under
9c3d31fe1Smrg the terms of the GNU General Public License as published by the Free
10c3d31fe1Smrg Software Foundation; either version 3, or (at your option) any later
11c3d31fe1Smrg version.
12c3d31fe1Smrg
13c3d31fe1Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14c3d31fe1Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
15c3d31fe1Smrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16c3d31fe1Smrg for more details.
17c3d31fe1Smrg
18c3d31fe1Smrg You should have received a copy of the GNU General Public License
19c3d31fe1Smrg along with GCC; see the file COPYING3. If not see
20c3d31fe1Smrg <http://www.gnu.org/licenses/>. */
21c3d31fe1Smrg
22c3d31fe1Smrg
23c3d31fe1Smrg #include "bconfig.h"
24c3d31fe1Smrg #include "system.h"
25c3d31fe1Smrg #include "coretypes.h"
26c3d31fe1Smrg #include "tm.h"
27c3d31fe1Smrg #include "rtl.h"
28c3d31fe1Smrg #include "obstack.h"
29c3d31fe1Smrg #include "errors.h"
30af526226Smrg #include "read-md.h"
31c3d31fe1Smrg #include "gensupport.h"
32c3d31fe1Smrg
33c3d31fe1Smrg /* Obstack to remember insns with. */
34c3d31fe1Smrg static struct obstack obstack;
35c3d31fe1Smrg
36c3d31fe1Smrg /* Max size of names encountered. */
37c3d31fe1Smrg static int max_id_len;
38c3d31fe1Smrg
39c3d31fe1Smrg /* Max operand encountered in a scan over some insn. */
40c3d31fe1Smrg static int max_opno;
41c3d31fe1Smrg
42c3d31fe1Smrg static void max_operand_1 (rtx);
43c3d31fe1Smrg static int num_operands (rtx);
44c3d31fe1Smrg static void gen_proto (rtx);
45c3d31fe1Smrg
46c3d31fe1Smrg /* Count the number of match_operand's found. */
47c3d31fe1Smrg
48c3d31fe1Smrg static void
max_operand_1(rtx x)49c3d31fe1Smrg max_operand_1 (rtx x)
50c3d31fe1Smrg {
51c3d31fe1Smrg RTX_CODE code;
52c3d31fe1Smrg int i;
53c3d31fe1Smrg int len;
54c3d31fe1Smrg const char *fmt;
55c3d31fe1Smrg
56c3d31fe1Smrg if (x == 0)
57c3d31fe1Smrg return;
58c3d31fe1Smrg
59c3d31fe1Smrg code = GET_CODE (x);
60c3d31fe1Smrg
61c3d31fe1Smrg if (code == MATCH_OPERAND || code == MATCH_OPERATOR
62c3d31fe1Smrg || code == MATCH_PARALLEL)
63c3d31fe1Smrg max_opno = MAX (max_opno, XINT (x, 0));
64c3d31fe1Smrg
65c3d31fe1Smrg fmt = GET_RTX_FORMAT (code);
66c3d31fe1Smrg len = GET_RTX_LENGTH (code);
67c3d31fe1Smrg for (i = 0; i < len; i++)
68c3d31fe1Smrg {
69c3d31fe1Smrg if (fmt[i] == 'e' || fmt[i] == 'u')
70c3d31fe1Smrg max_operand_1 (XEXP (x, i));
71c3d31fe1Smrg else if (fmt[i] == 'E')
72c3d31fe1Smrg {
73c3d31fe1Smrg int j;
74c3d31fe1Smrg for (j = 0; j < XVECLEN (x, i); j++)
75c3d31fe1Smrg max_operand_1 (XVECEXP (x, i, j));
76c3d31fe1Smrg }
77c3d31fe1Smrg }
78c3d31fe1Smrg }
79c3d31fe1Smrg
80c3d31fe1Smrg static int
num_operands(rtx insn)81c3d31fe1Smrg num_operands (rtx insn)
82c3d31fe1Smrg {
83c3d31fe1Smrg int len = XVECLEN (insn, 1);
84c3d31fe1Smrg int i;
85c3d31fe1Smrg
86c3d31fe1Smrg max_opno = -1;
87c3d31fe1Smrg
88c3d31fe1Smrg for (i = 0; i < len; i++)
89c3d31fe1Smrg max_operand_1 (XVECEXP (insn, 1, i));
90c3d31fe1Smrg
91c3d31fe1Smrg return max_opno + 1;
92c3d31fe1Smrg }
93c3d31fe1Smrg
94c3d31fe1Smrg /* Print out prototype information for a generator function. If the
95c3d31fe1Smrg insn pattern has been elided, print out a dummy generator that
96c3d31fe1Smrg does nothing. */
97c3d31fe1Smrg
98c3d31fe1Smrg static void
gen_proto(rtx insn)99c3d31fe1Smrg gen_proto (rtx insn)
100c3d31fe1Smrg {
101c3d31fe1Smrg int num = num_operands (insn);
102c3d31fe1Smrg int i;
103c3d31fe1Smrg const char *name = XSTR (insn, 0);
104c3d31fe1Smrg int truth = maybe_eval_c_test (XSTR (insn, 2));
105c3d31fe1Smrg
106c3d31fe1Smrg if (truth != 0)
107c3d31fe1Smrg printf ("extern rtx gen_%-*s (", max_id_len, name);
108c3d31fe1Smrg else
109c3d31fe1Smrg printf ("static inline rtx gen_%-*s (", max_id_len, name);
110c3d31fe1Smrg
111c3d31fe1Smrg if (num == 0)
112c3d31fe1Smrg fputs ("void", stdout);
113c3d31fe1Smrg else
114c3d31fe1Smrg {
115c3d31fe1Smrg for (i = 1; i < num; i++)
116c3d31fe1Smrg fputs ("rtx, ", stdout);
117c3d31fe1Smrg
118c3d31fe1Smrg fputs ("rtx", stdout);
119c3d31fe1Smrg }
120c3d31fe1Smrg
121c3d31fe1Smrg puts (");");
122c3d31fe1Smrg
123c3d31fe1Smrg /* Some back ends want to take the address of generator functions,
124c3d31fe1Smrg so we cannot simply use #define for these dummy definitions. */
125c3d31fe1Smrg if (truth == 0)
126c3d31fe1Smrg {
127c3d31fe1Smrg printf ("static inline rtx\ngen_%s", name);
128c3d31fe1Smrg if (num > 0)
129c3d31fe1Smrg {
130c3d31fe1Smrg putchar ('(');
131c3d31fe1Smrg for (i = 0; i < num-1; i++)
132c3d31fe1Smrg printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
133c3d31fe1Smrg printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
134c3d31fe1Smrg }
135c3d31fe1Smrg else
136c3d31fe1Smrg puts ("(void)");
137c3d31fe1Smrg puts ("{\n return 0;\n}");
138c3d31fe1Smrg }
139c3d31fe1Smrg
140c3d31fe1Smrg }
141c3d31fe1Smrg
142c3d31fe1Smrg static void
gen_insn(md_rtx_info * info)14363aace61Smrg gen_insn (md_rtx_info *info)
144c3d31fe1Smrg {
14563aace61Smrg rtx insn = info->def;
146c3d31fe1Smrg const char *name = XSTR (insn, 0);
147c3d31fe1Smrg const char *p;
148c3d31fe1Smrg const char *lt, *gt;
149c3d31fe1Smrg int len;
150c3d31fe1Smrg int truth = maybe_eval_c_test (XSTR (insn, 2));
151c3d31fe1Smrg
152c3d31fe1Smrg lt = strchr (name, '<');
153c3d31fe1Smrg if (lt && strchr (lt + 1, '>'))
154c3d31fe1Smrg {
15563aace61Smrg error_at (info->loc, "unresolved iterator");
156c3d31fe1Smrg return;
157c3d31fe1Smrg }
158c3d31fe1Smrg
159c3d31fe1Smrg gt = strchr (name, '>');
160c3d31fe1Smrg if (lt || gt)
161c3d31fe1Smrg {
16263aace61Smrg error_at (info->loc, "unmatched angle brackets, likely "
163c3d31fe1Smrg "an error in iterator syntax");
164c3d31fe1Smrg return;
165c3d31fe1Smrg }
166c3d31fe1Smrg
167c3d31fe1Smrg /* Don't mention instructions whose names are the null string
168c3d31fe1Smrg or begin with '*'. They are in the machine description just
169c3d31fe1Smrg to be recognized. */
170c3d31fe1Smrg if (name[0] == 0 || name[0] == '*')
171c3d31fe1Smrg return;
172c3d31fe1Smrg
173c3d31fe1Smrg len = strlen (name);
174c3d31fe1Smrg
175c3d31fe1Smrg if (len > max_id_len)
176c3d31fe1Smrg max_id_len = len;
177c3d31fe1Smrg
178c3d31fe1Smrg if (truth == 0)
179c3d31fe1Smrg /* Emit nothing. */;
180c3d31fe1Smrg else if (truth == 1)
181c3d31fe1Smrg printf ("#define HAVE_%s 1\n", name);
182c3d31fe1Smrg else
183c3d31fe1Smrg {
184c3d31fe1Smrg /* Write the macro definition, putting \'s at the end of each line,
185c3d31fe1Smrg if more than one. */
186c3d31fe1Smrg printf ("#define HAVE_%s (", name);
187c3d31fe1Smrg for (p = XSTR (insn, 2); *p; p++)
188c3d31fe1Smrg {
189c3d31fe1Smrg if (IS_VSPACE (*p))
190c3d31fe1Smrg fputs (" \\\n", stdout);
191c3d31fe1Smrg else
192c3d31fe1Smrg putchar (*p);
193c3d31fe1Smrg }
194c3d31fe1Smrg fputs (")\n", stdout);
195c3d31fe1Smrg }
196c3d31fe1Smrg
197c3d31fe1Smrg obstack_grow (&obstack, &insn, sizeof (rtx));
198c3d31fe1Smrg }
199c3d31fe1Smrg
200c3d31fe1Smrg int
main(int argc,const char ** argv)2016a5c9aabSmrg main (int argc, const char **argv)
202c3d31fe1Smrg {
203c3d31fe1Smrg rtx dummy;
204c3d31fe1Smrg rtx *insns;
205c3d31fe1Smrg rtx *insn_ptr;
206c3d31fe1Smrg
207c3d31fe1Smrg progname = "genflags";
208c3d31fe1Smrg obstack_init (&obstack);
209c3d31fe1Smrg
210c3d31fe1Smrg /* We need to see all the possibilities. Elided insns may have
211c3d31fe1Smrg direct calls to their generators in C code. */
212c3d31fe1Smrg insn_elision = 0;
213c3d31fe1Smrg
214af526226Smrg if (!init_rtx_reader_args (argc, argv))
215c3d31fe1Smrg return (FATAL_EXIT_CODE);
216c3d31fe1Smrg
217c3d31fe1Smrg puts ("/* Generated automatically by the program `genflags'");
218c3d31fe1Smrg puts (" from the machine description file `md'. */\n");
219c3d31fe1Smrg puts ("#ifndef GCC_INSN_FLAGS_H");
220c3d31fe1Smrg puts ("#define GCC_INSN_FLAGS_H\n");
221c3d31fe1Smrg
222c3d31fe1Smrg /* Read the machine description. */
223c3d31fe1Smrg
22463aace61Smrg md_rtx_info info;
22563aace61Smrg while (read_md_rtx (&info))
22663aace61Smrg switch (GET_CODE (info.def))
227c3d31fe1Smrg {
22863aace61Smrg case DEFINE_INSN:
22963aace61Smrg case DEFINE_EXPAND:
23063aace61Smrg gen_insn (&info);
231c3d31fe1Smrg break;
23263aace61Smrg
23363aace61Smrg default:
23463aace61Smrg break;
235c3d31fe1Smrg }
236c3d31fe1Smrg
237c3d31fe1Smrg /* Print out the prototypes now. */
238c3d31fe1Smrg dummy = (rtx) 0;
239c3d31fe1Smrg obstack_grow (&obstack, &dummy, sizeof (rtx));
240c3d31fe1Smrg insns = XOBFINISH (&obstack, rtx *);
241c3d31fe1Smrg
242c3d31fe1Smrg for (insn_ptr = insns; *insn_ptr; insn_ptr++)
243c3d31fe1Smrg gen_proto (*insn_ptr);
244c3d31fe1Smrg
245c3d31fe1Smrg puts ("\n#endif /* GCC_INSN_FLAGS_H */");
246c3d31fe1Smrg
247c3d31fe1Smrg if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
248c3d31fe1Smrg return FATAL_EXIT_CODE;
249c3d31fe1Smrg
250c3d31fe1Smrg return SUCCESS_EXIT_CODE;
251c3d31fe1Smrg }
252