source: trunk/third/gcc/genflags.c @ 11288

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