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, 1999 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 void fatal PVPROTO ((const char *, ...))
37 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
39 /* Names for patterns. Need to allow linking with print-rtl. */
42 /* Obstacks to remember normal, and call insns. */
43 static struct obstack call_obstack, normal_obstack;
45 /* Max size of names encountered. */
46 static int max_id_len;
48 static int num_operands PROTO((rtx));
49 static void gen_proto PROTO((rtx));
50 static void gen_nonproto PROTO((rtx));
51 static void gen_insn PROTO((rtx));
54 /* Count the number of match_operand's found. */
62 enum rtx_code code = GET_CODE (x);
63 const char *format_ptr = GET_RTX_FORMAT (code);
65 if (code == MATCH_OPERAND)
68 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
71 for (i = 0; i < GET_RTX_LENGTH (code); i++)
73 switch (*format_ptr++)
77 count += num_operands (XEXP (x, i));
81 if (XVEC (x, i) != NULL)
82 for (j = 0; j < XVECLEN (x, i); j++)
83 count += num_operands (XVECEXP (x, i, j));
92 /* Print out prototype information for a function. */
98 int num = num_operands (insn);
99 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
114 /* Print out a function declaration without a prototype. */
120 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
127 char *name = XSTR (insn, 0);
129 struct obstack *obstack_ptr;
132 /* Don't mention instructions whose names are the null string
133 or begin with '*'. They are in the machine description just
135 if (name[0] == 0 || name[0] == '*')
140 if (len > max_id_len)
143 printf ("#define HAVE_%s ", name);
144 if (strlen (XSTR (insn, 2)) == 0)
148 /* Write the macro definition, putting \'s at the end of each line,
151 for (p = XSTR (insn, 2); *p; p++)
161 /* Save the current insn, so that we can later put out appropriate
162 prototypes. At present, most md files have the wrong number of
163 arguments for the call insns (call, call_value, call_pop,
164 call_value_pop) ignoring the extra arguments that are passed for
165 some machines, so by default, turn off the prototype. */
167 obstack_ptr = (name[0] == 'c'
168 && (!strcmp (name, "call")
169 || !strcmp (name, "call_value")
170 || !strcmp (name, "call_pop")
171 || !strcmp (name, "call_value_pop")))
172 ? &call_obstack : &normal_obstack;
174 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
181 register PTR val = (PTR) malloc (size);
184 fatal ("virtual memory exhausted");
196 ptr = (PTR) realloc (old, size);
198 ptr = (PTR) malloc (size);
200 fatal ("virtual memory exhausted");
205 fatal VPROTO ((const char *format, ...))
207 #ifndef ANSI_PROTOTYPES
212 VA_START (ap, format);
214 #ifndef ANSI_PROTOTYPES
215 format = va_arg (ap, const char *);
218 fprintf (stderr, "genflags: ");
219 vfprintf (stderr, format, ap);
221 fprintf (stderr, "\n");
222 exit (FATAL_EXIT_CODE);
238 obstack_init (rtl_obstack);
239 obstack_init (&call_obstack);
240 obstack_init (&normal_obstack);
243 fatal ("No input file name.");
245 infile = fopen (argv[1], "r");
249 exit (FATAL_EXIT_CODE);
254 printf ("/* Generated automatically by the program `genflags'\n\
255 from the machine description file `md'. */\n\n");
257 /* Read the machine description. */
261 c = read_skip_spaces (infile);
266 desc = read_rtx (infile);
267 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
271 /* Print out the prototypes now. */
273 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
274 call_insns = (rtx *) obstack_finish (&call_obstack);
276 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
277 normal_insns = (rtx *) obstack_finish (&normal_obstack);
279 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
280 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
281 gen_proto (*insn_ptr);
283 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
284 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
285 gen_proto (*insn_ptr);
287 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
288 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
289 gen_nonproto (*insn_ptr);
291 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
292 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
293 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
294 gen_nonproto (*insn_ptr);
296 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
297 gen_nonproto (*insn_ptr);
299 printf ("#endif /* NO_MD_PROTOTYPES */\n");
302 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);