1 /* Generate from machine description:
3 - some flags HAVE_... saying which simple standard instructions are
4 available for this machine.
5 Copyright (C) 1987, 1991, 1995, 1998 Free Software Foundation, Inc.
7 This file is part of GNU CC.
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)
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.
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. */
30 static struct obstack obstack;
31 struct obstack *rtl_obstack = &obstack;
33 #define obstack_chunk_alloc xmalloc
34 #define obstack_chunk_free free
36 char *xmalloc PROTO((unsigned));
37 static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
38 void fancy_abort PROTO((void));
40 /* Names for patterns. Need to allow linking with print-rtl. */
43 /* Obstacks to remember normal, and call insns. */
44 static struct obstack call_obstack, normal_obstack;
46 /* Max size of names encountered. */
47 static int max_id_len;
49 static int num_operands PROTO((rtx));
50 static void gen_proto PROTO((rtx));
51 static void gen_nonproto PROTO((rtx));
52 static void gen_insn PROTO((rtx));
55 /* Count the number of match_operand's found. */
63 enum rtx_code code = GET_CODE (x);
64 char *format_ptr = GET_RTX_FORMAT (code);
66 if (code == MATCH_OPERAND)
69 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
72 for (i = 0; i < GET_RTX_LENGTH (code); i++)
74 switch (*format_ptr++)
78 count += num_operands (XEXP (x, i));
82 if (XVEC (x, i) != NULL)
83 for (j = 0; j < XVECLEN (x, i); j++)
84 count += num_operands (XVECEXP (x, i, j));
93 /* Print out prototype information for a function. */
99 int num = num_operands (insn);
100 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
115 /* Print out a function declaration without a prototype. */
121 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
128 char *name = XSTR (insn, 0);
130 struct obstack *obstack_ptr;
133 /* Don't mention instructions whose names are the null string
134 or begin with '*'. They are in the machine description just
136 if (name[0] == 0 || name[0] == '*')
141 if (len > max_id_len)
144 printf ("#define HAVE_%s ", name);
145 if (strlen (XSTR (insn, 2)) == 0)
149 /* Write the macro definition, putting \'s at the end of each line,
152 for (p = XSTR (insn, 2); *p; p++)
162 /* Save the current insn, so that we can later put out appropriate
163 prototypes. At present, most md files have the wrong number of
164 arguments for the call insns (call, call_value, call_pop,
165 call_value_pop) ignoring the extra arguments that are passed for
166 some machines, so by default, turn off the prototype. */
168 obstack_ptr = (name[0] == 'c'
169 && (!strcmp (name, "call")
170 || !strcmp (name, "call_value")
171 || !strcmp (name, "call_pop")
172 || !strcmp (name, "call_value_pop")))
173 ? &call_obstack : &normal_obstack;
175 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
182 register char *val = (char *) malloc (size);
185 fatal ("virtual memory exhausted");
195 char *result = (char *) realloc (ptr, size);
197 fatal ("virtual memory exhausted");
202 fatal VPROTO ((char *format, ...))
209 VA_START (ap, format);
212 format = va_arg (ap, char *);
215 fprintf (stderr, "genflags: ");
216 vfprintf (stderr, format, ap);
218 fprintf (stderr, "\n");
219 exit (FATAL_EXIT_CODE);
222 /* More 'friendly' abort that prints the line and file.
223 config.h can #define abort fancy_abort if you like that sort of thing. */
228 fatal ("Internal gcc abort.");
244 obstack_init (rtl_obstack);
245 obstack_init (&call_obstack);
246 obstack_init (&normal_obstack);
249 fatal ("No input file name.");
251 infile = fopen (argv[1], "r");
255 exit (FATAL_EXIT_CODE);
260 printf ("/* Generated automatically by the program `genflags'\n\
261 from the machine description file `md'. */\n\n");
263 /* Read the machine description. */
267 c = read_skip_spaces (infile);
272 desc = read_rtx (infile);
273 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
277 /* Print out the prototypes now. */
279 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
280 call_insns = (rtx *) obstack_finish (&call_obstack);
282 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
283 normal_insns = (rtx *) obstack_finish (&normal_obstack);
285 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
286 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
287 gen_proto (*insn_ptr);
289 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
290 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
291 gen_proto (*insn_ptr);
293 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
294 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
295 gen_nonproto (*insn_ptr);
297 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
298 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
299 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
300 gen_nonproto (*insn_ptr);
302 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
303 gen_nonproto (*insn_ptr);
305 printf ("#endif /* NO_MD_PROTOTYPES */\n");
308 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);