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. */
31 static struct obstack obstack;
32 struct obstack *rtl_obstack = &obstack;
34 #define obstack_chunk_alloc xmalloc
35 #define obstack_chunk_free free
37 /* Names for patterns. Need to allow linking with print-rtl. */
40 /* Obstacks to remember normal, and call insns. */
41 static struct obstack call_obstack, normal_obstack;
43 /* Max size of names encountered. */
44 static int max_id_len;
46 static int num_operands PROTO((rtx));
47 static void gen_proto PROTO((rtx));
48 static void gen_nonproto PROTO((rtx));
49 static void gen_insn PROTO((rtx));
52 /* Count the number of match_operand's found. */
60 enum rtx_code code = GET_CODE (x);
61 const char *format_ptr = GET_RTX_FORMAT (code);
63 if (code == MATCH_OPERAND)
66 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
69 for (i = 0; i < GET_RTX_LENGTH (code); i++)
71 switch (*format_ptr++)
75 count += num_operands (XEXP (x, i));
79 if (XVEC (x, i) != NULL)
80 for (j = 0; j < XVECLEN (x, i); j++)
81 count += num_operands (XVECEXP (x, i, j));
90 /* Print out prototype information for a function. */
96 int num = num_operands (insn);
97 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
112 /* Print out a function declaration without a prototype. */
118 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
125 char *name = XSTR (insn, 0);
127 struct obstack *obstack_ptr;
130 /* Don't mention instructions whose names are the null string
131 or begin with '*'. They are in the machine description just
133 if (name[0] == 0 || name[0] == '*')
138 if (len > max_id_len)
141 printf ("#define HAVE_%s ", name);
142 if (strlen (XSTR (insn, 2)) == 0)
146 /* Write the macro definition, putting \'s at the end of each line,
149 for (p = XSTR (insn, 2); *p; p++)
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. */
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;
172 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
179 register PTR val = (PTR) malloc (size);
182 fatal ("virtual memory exhausted");
194 ptr = (PTR) realloc (old, size);
196 ptr = (PTR) malloc (size);
198 fatal ("virtual memory exhausted");
215 progname = "genflags";
216 obstack_init (rtl_obstack);
217 obstack_init (&call_obstack);
218 obstack_init (&normal_obstack);
221 fatal ("No input file name.");
223 infile = fopen (argv[1], "r");
227 exit (FATAL_EXIT_CODE);
230 printf ("/* Generated automatically by the program `genflags'\n\
231 from the machine description file `md'. */\n\n");
233 /* Read the machine description. */
237 c = read_skip_spaces (infile);
242 desc = read_rtx (infile);
243 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
247 /* Print out the prototypes now. */
249 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
250 call_insns = (rtx *) obstack_finish (&call_obstack);
252 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
253 normal_insns = (rtx *) obstack_finish (&normal_obstack);
255 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
256 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
257 gen_proto (*insn_ptr);
259 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
260 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
261 gen_proto (*insn_ptr);
263 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
264 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
265 gen_nonproto (*insn_ptr);
267 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
268 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
269 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
270 gen_nonproto (*insn_ptr);
272 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
273 gen_nonproto (*insn_ptr);
275 printf ("#endif /* NO_MD_PROTOTYPES */\n");
278 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);