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

Revision 8834, 6.6 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, 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.  */
53static int
54num_operands (x)
55     rtx x;
56{
57  int count = 0;
58  int i, j;
59  enum rtx_code code = GET_CODE (x);
60  char *format_ptr = GET_RTX_FORMAT (code);
61
62  if (code == MATCH_OPERAND)
63    return 1;
64
65  if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
66    count++;
67
68  for (i = 0; i < GET_RTX_LENGTH (code); i++)
69    {
70      switch (*format_ptr++)
71        {
72        case 'u':
73        case 'e':
74          count += num_operands (XEXP (x, i));
75          break;
76
77        case 'E':
78          if (XVEC (x, i) != NULL)
79            for (j = 0; j < XVECLEN (x, i); j++)
80              count += num_operands (XVECEXP (x, i, j));
81
82          break;
83        }
84    }
85
86  return count;
87}
88
89/* Print out prototype information for a function.  */
90static void
91gen_proto (insn)
92     rtx insn;
93{
94  int num = num_operands (insn);
95  printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
96
97  if (num == 0)
98    printf ("void");
99  else
100    {
101      while (num-- > 1)
102        printf ("rtx, ");
103
104      printf ("rtx");
105    }
106
107  printf ("));\n");
108}
109
110/* Print out a function declaration without a prototype.  */
111static void
112gen_nonproto (insn)
113     rtx insn;
114{
115  printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
116}
117
118static void
119gen_insn (insn)
120     rtx insn;
121{
122  char *name = XSTR (insn, 0);
123  char *p;
124  struct obstack *obstack_ptr;
125  int len;
126
127  /* Don't mention instructions whose names are the null string
128     or begin with '*'.  They are in the machine description just
129     to be recognized.  */
130  if (name[0] == 0 || name[0] == '*')
131    return;
132
133  len = strlen (name);
134
135  if (len > max_id_len)
136    max_id_len = len;
137
138  printf ("#define HAVE_%s ", name);
139  if (strlen (XSTR (insn, 2)) == 0)
140    printf ("1\n");
141  else
142    {
143      /* Write the macro definition, putting \'s at the end of each line,
144         if more than one.  */
145      printf ("(");
146      for (p = XSTR (insn, 2); *p; p++)
147        {
148          if (*p == '\n')
149            printf (" \\\n");
150          else
151            printf ("%c", *p);
152        }
153      printf (")\n");
154    }
155
156  /* Save the current insn, so that we can later put out appropriate
157     prototypes.  At present, most md files have the wrong number of
158     arguments for the call insns (call, call_value, call_pop,
159     call_value_pop) ignoring the extra arguments that are passed for
160     some machines, so by default, turn off the prototype.  */
161
162  obstack_ptr = (name[0] == 'c'
163                 && (!strcmp (name, "call")
164                     || !strcmp (name, "call_value")
165                     || !strcmp (name, "call_pop")
166                     || !strcmp (name, "call_value_pop")))
167    ? &call_obstack : &normal_obstack;
168
169  obstack_grow (obstack_ptr, &insn, sizeof (rtx));
170}
171
172char *
173xmalloc (size)
174     unsigned size;
175{
176  register char *val = (char *) malloc (size);
177
178  if (val == 0)
179    fatal ("virtual memory exhausted");
180
181  return val;
182}
183
184char *
185xrealloc (ptr, size)
186     char *ptr;
187     unsigned size;
188{
189  char *result = (char *) realloc (ptr, size);
190  if (!result)
191    fatal ("virtual memory exhausted");
192  return result;
193}
194
195static void
196fatal (s, a1, a2)
197     char *s;
198{
199  fprintf (stderr, "genflags: ");
200  fprintf (stderr, s, a1, a2);
201  fprintf (stderr, "\n");
202  exit (FATAL_EXIT_CODE);
203}
204
205/* More 'friendly' abort that prints the line and file.
206   config.h can #define abort fancy_abort if you like that sort of thing.  */
207
208void
209fancy_abort ()
210{
211  fatal ("Internal gcc abort.");
212}
213
214int
215main (argc, argv)
216     int argc;
217     char **argv;
218{
219  rtx desc;
220  rtx dummy;
221  rtx *call_insns;
222  rtx *normal_insns;
223  rtx *insn_ptr;
224  FILE *infile;
225  register int c;
226
227  obstack_init (rtl_obstack);
228  obstack_init (&call_obstack);
229  obstack_init (&normal_obstack);
230
231  if (argc <= 1)
232    fatal ("No input file name.");
233
234  infile = fopen (argv[1], "r");
235  if (infile == 0)
236    {
237      perror (argv[1]);
238      exit (FATAL_EXIT_CODE);
239    }
240
241  init_rtl ();
242
243  printf ("/* Generated automatically by the program `genflags'\n\
244from the machine description file `md'.  */\n\n");
245
246  /* Read the machine description.  */
247
248  while (1)
249    {
250      c = read_skip_spaces (infile);
251      if (c == EOF)
252        break;
253      ungetc (c, infile);
254
255      desc = read_rtx (infile);
256      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
257        gen_insn (desc);
258    }
259
260  /* Print out the prototypes now.  */
261  dummy = (rtx)0;
262  obstack_grow (&call_obstack, &dummy, sizeof (rtx));
263  call_insns = (rtx *) obstack_finish (&call_obstack);
264
265  obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
266  normal_insns = (rtx *) obstack_finish (&normal_obstack);
267
268  printf ("\n#ifndef NO_MD_PROTOTYPES\n");
269  for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
270    gen_proto (*insn_ptr);
271
272  printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
273  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
274    gen_proto (*insn_ptr);
275
276  printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
277  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
278    gen_nonproto (*insn_ptr);
279
280  printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
281  printf ("\n#else  /* NO_MD_PROTOTYPES */\n");
282  for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
283    gen_nonproto (*insn_ptr);
284
285  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
286    gen_nonproto (*insn_ptr);
287
288  printf ("#endif  /* NO_MD_PROTOTYPES */\n");
289
290  fflush (stdout);
291  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
292  /* NOTREACHED */
293  return 0;
294}
Note: See TracBrowser for help on using the repository browser.