1 /* Generate from machine description:
2 - some flags HAVE_... saying which simple standard instructions are
3 available for this machine.
4 Copyright (C) 1987, 1991, 1995, 1998, 1999 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 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 /* Names for patterns. Need to allow linking with print-rtl. */
39 /* Obstacks to remember normal, and call insns. */
40 static struct obstack call_obstack, normal_obstack;
42 /* Max size of names encountered. */
43 static int max_id_len;
45 static int num_operands PROTO((rtx));
46 static void gen_proto PROTO((rtx));
47 static void gen_nonproto PROTO((rtx));
48 static void gen_insn PROTO((rtx));
51 /* Count the number of match_operand's found. */
59 enum rtx_code code = GET_CODE (x);
60 const char *format_ptr = GET_RTX_FORMAT (code);
62 if (code == MATCH_OPERAND)
65 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
68 for (i = 0; i < GET_RTX_LENGTH (code); i++)
70 switch (*format_ptr++)
74 count += num_operands (XEXP (x, i));
78 if (XVEC (x, i) != NULL)
79 for (j = 0; j < XVECLEN (x, i); j++)
80 count += num_operands (XVECEXP (x, i, j));
89 /* Print out prototype information for a function. */
95 int num = num_operands (insn);
96 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
111 /* Print out a function declaration without a prototype. */
117 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
124 char *name = XSTR (insn, 0);
126 struct obstack *obstack_ptr;
129 /* Don't mention instructions whose names are the null string
130 or begin with '*'. They are in the machine description just
132 if (name[0] == 0 || name[0] == '*')
137 if (len > max_id_len)
140 printf ("#define HAVE_%s ", name);
141 if (strlen (XSTR (insn, 2)) == 0)
145 /* Write the macro definition, putting \'s at the end of each line,
148 for (p = XSTR (insn, 2); *p; p++)
158 /* Save the current insn, so that we can later put out appropriate
159 prototypes. At present, most md files have the wrong number of
160 arguments for the call insns (call, call_value, call_pop,
161 call_value_pop) ignoring the extra arguments that are passed for
162 some machines, so by default, turn off the prototype. */
164 obstack_ptr = (name[0] == 'c'
165 && (!strcmp (name, "call")
166 || !strcmp (name, "call_value")
167 || !strcmp (name, "call_pop")
168 || !strcmp (name, "call_value_pop")))
169 ? &call_obstack : &normal_obstack;
171 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
178 register PTR val = (PTR) malloc (size);
181 fatal ("virtual memory exhausted");
193 ptr = (PTR) realloc (old, size);
195 ptr = (PTR) malloc (size);
197 fatal ("virtual memory exhausted");
214 progname = "genflags";
215 obstack_init (rtl_obstack);
216 obstack_init (&call_obstack);
217 obstack_init (&normal_obstack);
220 fatal ("No input file name.");
222 infile = fopen (argv[1], "r");
226 exit (FATAL_EXIT_CODE);
229 printf ("/* Generated automatically by the program `genflags'\n\
230 from the machine description file `md'. */\n\n");
232 /* Read the machine description. */
236 c = read_skip_spaces (infile);
241 desc = read_rtx (infile);
242 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
246 /* Print out the prototypes now. */
248 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
249 call_insns = (rtx *) obstack_finish (&call_obstack);
251 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
252 normal_insns = (rtx *) obstack_finish (&normal_obstack);
254 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
255 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
256 gen_proto (*insn_ptr);
258 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
259 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
260 gen_proto (*insn_ptr);
262 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
263 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
264 gen_nonproto (*insn_ptr);
266 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
267 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
268 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
269 gen_nonproto (*insn_ptr);
271 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
272 gen_nonproto (*insn_ptr);
274 printf ("#endif /* NO_MD_PROTOTYPES */\n");
277 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);