OSDN Git Service

* config/sparc/sparc.md (movdi_insn_sp64_novis): New pattern.
[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,
5    1999, 2000 Free Software Foundation, Inc.
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24
25 #include "hconfig.h"
26 #include "system.h"
27 #include "rtl.h"
28 #include "obstack.h"
29 #include "errors.h"
30
31 static struct obstack obstack;
32 struct obstack *rtl_obstack = &obstack;
33
34 #define obstack_chunk_alloc xmalloc
35 #define obstack_chunk_free free
36
37 /* Obstacks to remember normal, and call insns.  */
38 static struct obstack call_obstack, normal_obstack;
39
40 /* Max size of names encountered.  */
41 static int max_id_len;
42
43 /* Max operand encountered in a scan over some insn.  */
44 static int max_opno;
45
46 static void max_operand_1       PARAMS ((rtx));
47 static int num_operands         PARAMS ((rtx));
48 static void gen_proto           PARAMS ((rtx));
49 static void gen_nonproto        PARAMS ((rtx));
50 static void gen_insn            PARAMS ((rtx));
51
52 /* Count the number of match_operand's found.  */
53
54 static void
55 max_operand_1 (x)
56      rtx x;
57 {
58   register RTX_CODE code;
59   register int i;
60   register int len;
61   register const char *fmt;
62
63   if (x == 0)
64     return;
65
66   code = GET_CODE (x);
67
68   if (code == MATCH_OPERAND || code == MATCH_OPERATOR
69       || code == MATCH_PARALLEL)
70     max_opno = MAX (max_opno, XINT (x, 0));
71
72   fmt = GET_RTX_FORMAT (code);
73   len = GET_RTX_LENGTH (code);
74   for (i = 0; i < len; i++)
75     {
76       if (fmt[i] == 'e' || fmt[i] == 'u')
77         max_operand_1 (XEXP (x, i));
78       else if (fmt[i] == 'E')
79         {
80           int j;
81           for (j = 0; j < XVECLEN (x, i); j++)
82             max_operand_1 (XVECEXP (x, i, j));
83         }
84     }
85 }
86
87 static int
88 num_operands (insn)
89      rtx insn;
90 {
91   register int len = XVECLEN (insn, 1);
92   register int i;
93
94   max_opno = -1;
95
96   for (i = 0; i < len; i++)
97     max_operand_1 (XVECEXP (insn, 1, i));
98
99   return max_opno + 1;
100 }
101
102 /* Print out prototype information for a function.  */
103
104 static void
105 gen_proto (insn)
106      rtx insn;
107 {
108   int num = num_operands (insn);
109   printf ("extern rtx gen_%-*s PARAMS ((", max_id_len, XSTR (insn, 0));
110
111   if (num == 0)
112     printf ("void");
113   else
114     {
115       while (num-- > 1)
116         printf ("rtx, ");
117
118       printf ("rtx");
119     }
120
121   printf ("));\n");
122 }
123
124 /* Print out a function declaration without a prototype.  */
125
126 static void
127 gen_nonproto (insn)
128      rtx insn;
129 {
130   printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
131 }
132
133 static void
134 gen_insn (insn)
135      rtx insn;
136 {
137   const char *name = XSTR (insn, 0);
138   const char *p;
139   struct obstack *obstack_ptr;
140   int len;
141
142   /* Don't mention instructions whose names are the null string
143      or begin with '*'.  They are in the machine description just
144      to be recognized.  */
145   if (name[0] == 0 || name[0] == '*')
146     return;
147
148   len = strlen (name);
149
150   if (len > max_id_len)
151     max_id_len = len;
152
153   printf ("#define HAVE_%s ", name);
154   if (strlen (XSTR (insn, 2)) == 0)
155     printf ("1\n");
156   else
157     {
158       /* Write the macro definition, putting \'s at the end of each line,
159          if more than one.  */
160       printf ("(");
161       for (p = XSTR (insn, 2); *p; p++)
162         {
163           if (*p == '\n')
164             printf (" \\\n");
165           else
166             printf ("%c", *p);
167         }
168       printf (")\n");
169     }
170
171   /* Save the current insn, so that we can later put out appropriate
172      prototypes.  At present, most md files have the wrong number of
173      arguments for the call insns (call, call_value, call_pop,
174      call_value_pop) ignoring the extra arguments that are passed for
175      some machines, so by default, turn off the prototype.  */
176
177   obstack_ptr = ((name[0] == 'c' || name[0] == 's')
178                  && (!strcmp (name, "call")
179                      || !strcmp (name, "call_value")
180                      || !strcmp (name, "call_pop")
181                      || !strcmp (name, "call_value_pop")
182                      || !strcmp (name, "sibcall")
183                      || !strcmp (name, "sibcall_value")
184                      || !strcmp (name, "sibcall_pop")
185                      || !strcmp (name, "sibcall_value_pop")))
186     ? &call_obstack : &normal_obstack;
187
188   obstack_grow (obstack_ptr, &insn, sizeof (rtx));
189 }
190 \f
191 PTR
192 xmalloc (size)
193   size_t size;
194 {
195   register PTR val = (PTR) malloc (size);
196
197   if (val == 0)
198     fatal ("virtual memory exhausted");
199
200   return val;
201 }
202
203 PTR
204 xrealloc (old, size)
205   PTR old;
206   size_t size;
207 {
208   register PTR ptr;
209   if (old)
210     ptr = (PTR) realloc (old, size);
211   else
212     ptr = (PTR) malloc (size);
213   if (!ptr)
214     fatal ("virtual memory exhausted");
215   return ptr;
216 }
217
218 extern int main PARAMS ((int, char **));
219
220 int
221 main (argc, argv)
222      int argc;
223      char **argv;
224 {
225   rtx desc;
226   rtx dummy;
227   rtx *call_insns;
228   rtx *normal_insns;
229   rtx *insn_ptr;
230   FILE *infile;
231   register int c;
232
233   progname = "genflags";
234   obstack_init (rtl_obstack);
235   obstack_init (&call_obstack);
236   obstack_init (&normal_obstack);
237
238   if (argc <= 1)
239     fatal ("No input file name.");
240
241   infile = fopen (argv[1], "r");
242   if (infile == 0)
243     {
244       perror (argv[1]);
245       return (FATAL_EXIT_CODE);
246     }
247   read_rtx_filename = argv[1];
248
249   printf ("/* Generated automatically by the program `genflags'\n\
250 from the machine description file `md'.  */\n\n");
251
252   /* Read the machine description.  */
253
254   while (1)
255     {
256       c = read_skip_spaces (infile);
257       if (c == EOF)
258         break;
259       ungetc (c, infile);
260
261       desc = read_rtx (infile);
262       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
263         gen_insn (desc);
264     }
265
266   /* Print out the prototypes now.  */
267   dummy = (rtx) 0;
268   obstack_grow (&call_obstack, &dummy, sizeof (rtx));
269   call_insns = (rtx *) obstack_finish (&call_obstack);
270
271   obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
272   normal_insns = (rtx *) obstack_finish (&normal_obstack);
273
274   for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
275     gen_proto (*insn_ptr);
276
277   printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
278   for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
279     gen_proto (*insn_ptr);
280
281   printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
282   for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
283     gen_nonproto (*insn_ptr);
284
285   printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
286
287   fflush (stdout);
288   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
289 }
290
291 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
292 const char *
293 get_insn_name (code)
294      int code ATTRIBUTE_UNUSED;
295 {
296   return NULL;
297 }