OSDN Git Service

* dwarf2out.c (gen_compile_unit_die): Use DW_LANG_Go for Go.
[pf3gnuchains/gcc-fork.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, 1999, 2000, 2003, 2004, 2007, 2010
5    Free Software Foundation, Inc.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23
24 #include "bconfig.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "obstack.h"
30 #include "errors.h"
31 #include "read-md.h"
32 #include "gensupport.h"
33
34 /* Obstack to remember insns with.  */
35 static struct obstack obstack;
36
37 /* Max size of names encountered.  */
38 static int max_id_len;
39
40 /* Max operand encountered in a scan over some insn.  */
41 static int max_opno;
42
43 static void max_operand_1 (rtx);
44 static int num_operands (rtx);
45 static void gen_proto (rtx);
46 static void gen_macro (const char *, int, int);
47 static void gen_insn (int, rtx);
48
49 /* Count the number of match_operand's found.  */
50
51 static void
52 max_operand_1 (rtx x)
53 {
54   RTX_CODE code;
55   int i;
56   int len;
57   const char *fmt;
58
59   if (x == 0)
60     return;
61
62   code = GET_CODE (x);
63
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++)
71     {
72       if (fmt[i] == 'e' || fmt[i] == 'u')
73         max_operand_1 (XEXP (x, i));
74       else if (fmt[i] == 'E')
75         {
76           int j;
77           for (j = 0; j < XVECLEN (x, i); j++)
78             max_operand_1 (XVECEXP (x, i, j));
79         }
80     }
81 }
82
83 static int
84 num_operands (rtx insn)
85 {
86   int len = XVECLEN (insn, 1);
87   int i;
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;
95 }
96
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.  */
100 static void
101 gen_macro (const char *name, int real, int expect)
102 {
103   int i;
104
105   gcc_assert (real <= expect);
106   gcc_assert (real);
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
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.  */
126
127 static void
128 gen_proto (rtx insn)
129 {
130   int num = num_operands (insn);
131   int i;
132   const char *name = XSTR (insn, 0);
133   int truth = maybe_eval_c_test (XSTR (insn, 2));
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
154   if (truth != 0)
155     printf ("extern rtx        gen_%-*s (", max_id_len, name);
156   else
157     printf ("static inline rtx gen_%-*s (", max_id_len, name);
158
159   if (num == 0)
160     fputs ("void", stdout);
161   else
162     {
163       for (i = 1; i < num; i++)
164         fputs ("rtx, ", stdout);
165
166       fputs ("rtx", stdout);
167     }
168
169   puts (");");
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++)
180             printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
181           printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
182         }
183       else
184         puts ("(void)");
185       puts ("{\n  return 0;\n}");
186     }
187
188 }
189
190 static void
191 gen_insn (int line_no, rtx insn)
192 {
193   const char *name = XSTR (insn, 0);
194   const char *p;
195   const char *lt, *gt;
196   int len;
197   int truth = maybe_eval_c_test (XSTR (insn, 2));
198
199   lt = strchr (name, '<');
200   if (lt && strchr (lt + 1, '>'))
201     {
202       message_with_line (line_no, "unresolved iterator");
203       have_error = 1;
204       return;
205     }
206
207   gt = strchr (name, '>');
208   if (lt || gt)
209     {
210       message_with_line (line_no,
211                          "unmatched angle brackets, likely "
212                          "an error in iterator syntax");
213       have_error = 1;
214       return;
215     }
216
217   /* Don't mention instructions whose names are the null string
218      or begin with '*'.  They are in the machine description just
219      to be recognized.  */
220   if (name[0] == 0 || name[0] == '*')
221     return;
222
223   len = strlen (name);
224
225   if (len > max_id_len)
226     max_id_len = len;
227
228   if (truth == 0)
229     /* Emit nothing.  */;
230   else if (truth == 1)
231     printf ("#define HAVE_%s 1\n", name);
232   else
233     {
234       /* Write the macro definition, putting \'s at the end of each line,
235          if more than one.  */
236       printf ("#define HAVE_%s (", name);
237       for (p = XSTR (insn, 2); *p; p++)
238         {
239           if (IS_VSPACE (*p))
240             fputs (" \\\n", stdout);
241           else
242             putchar (*p);
243         }
244       fputs (")\n", stdout);
245     }
246
247   obstack_grow (&obstack, &insn, sizeof (rtx));
248 }
249
250 int
251 main (int argc, char **argv)
252 {
253   rtx desc;
254   rtx dummy;
255   rtx *insns;
256   rtx *insn_ptr;
257
258   progname = "genflags";
259   obstack_init (&obstack);
260
261   /* We need to see all the possibilities.  Elided insns may have
262      direct calls to their generators in C code.  */
263   insn_elision = 0;
264
265   if (!init_rtx_reader_args (argc, argv))
266     return (FATAL_EXIT_CODE);
267
268   puts ("/* Generated automatically by the program `genflags'");
269   puts ("   from the machine description file `md'.  */\n");
270   puts ("#ifndef GCC_INSN_FLAGS_H");
271   puts ("#define GCC_INSN_FLAGS_H\n");
272
273   /* Read the machine description.  */
274
275   while (1)
276     {
277       int line_no, insn_code_number = 0;
278
279       desc = read_md_rtx (&line_no, &insn_code_number);
280       if (desc == NULL)
281         break;
282       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
283         gen_insn (line_no, desc);
284     }
285
286   /* Print out the prototypes now.  */
287   dummy = (rtx) 0;
288   obstack_grow (&obstack, &dummy, sizeof (rtx));
289   insns = XOBFINISH (&obstack, rtx *);
290
291   for (insn_ptr = insns; *insn_ptr; insn_ptr++)
292     gen_proto (*insn_ptr);
293
294   puts("\n#endif /* GCC_INSN_FLAGS_H */");
295
296   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
297     return FATAL_EXIT_CODE;
298
299   return SUCCESS_EXIT_CODE;
300 }