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 *, ...))
38 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
39 void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
41 /* Names for patterns. Need to allow linking with print-rtl. */
44 /* Obstacks to remember normal, and call insns. */
45 static struct obstack call_obstack, normal_obstack;
47 /* Max size of names encountered. */
48 static int max_id_len;
50 static int num_operands PROTO((rtx));
51 static void gen_proto PROTO((rtx));
52 static void gen_nonproto PROTO((rtx));
53 static void gen_insn PROTO((rtx));
56 /* Count the number of match_operand's found. */
64 enum rtx_code code = GET_CODE (x);
65 char *format_ptr = GET_RTX_FORMAT (code);
67 if (code == MATCH_OPERAND)
70 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
73 for (i = 0; i < GET_RTX_LENGTH (code); i++)
75 switch (*format_ptr++)
79 count += num_operands (XEXP (x, i));
83 if (XVEC (x, i) != NULL)
84 for (j = 0; j < XVECLEN (x, i); j++)
85 count += num_operands (XVECEXP (x, i, j));
94 /* Print out prototype information for a function. */
100 int num = num_operands (insn);
101 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
116 /* Print out a function declaration without a prototype. */
122 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
129 char *name = XSTR (insn, 0);
131 struct obstack *obstack_ptr;
134 /* Don't mention instructions whose names are the null string
135 or begin with '*'. They are in the machine description just
137 if (name[0] == 0 || name[0] == '*')
142 if (len > max_id_len)
145 printf ("#define HAVE_%s ", name);
146 if (strlen (XSTR (insn, 2)) == 0)
150 /* Write the macro definition, putting \'s at the end of each line,
153 for (p = XSTR (insn, 2); *p; p++)
163 /* Save the current insn, so that we can later put out appropriate
164 prototypes. At present, most md files have the wrong number of
165 arguments for the call insns (call, call_value, call_pop,
166 call_value_pop) ignoring the extra arguments that are passed for
167 some machines, so by default, turn off the prototype. */
169 obstack_ptr = (name[0] == 'c'
170 && (!strcmp (name, "call")
171 || !strcmp (name, "call_value")
172 || !strcmp (name, "call_pop")
173 || !strcmp (name, "call_value_pop")))
174 ? &call_obstack : &normal_obstack;
176 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
183 register char *val = (char *) malloc (size);
186 fatal ("virtual memory exhausted");
196 char *result = (char *) realloc (ptr, size);
198 fatal ("virtual memory exhausted");
203 fatal VPROTO ((char *format, ...))
210 VA_START (ap, format);
213 format = va_arg (ap, char *);
216 fprintf (stderr, "genflags: ");
217 vfprintf (stderr, format, ap);
219 fprintf (stderr, "\n");
220 exit (FATAL_EXIT_CODE);
223 /* More 'friendly' abort that prints the line and file.
224 config.h can #define abort fancy_abort if you like that sort of thing. */
229 fatal ("Internal gcc abort.");
245 obstack_init (rtl_obstack);
246 obstack_init (&call_obstack);
247 obstack_init (&normal_obstack);
250 fatal ("No input file name.");
252 infile = fopen (argv[1], "r");
256 exit (FATAL_EXIT_CODE);
261 printf ("/* Generated automatically by the program `genflags'\n\
262 from the machine description file `md'. */\n\n");
264 /* Read the machine description. */
268 c = read_skip_spaces (infile);
273 desc = read_rtx (infile);
274 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
278 /* Print out the prototypes now. */
280 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
281 call_insns = (rtx *) obstack_finish (&call_obstack);
283 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
284 normal_insns = (rtx *) obstack_finish (&normal_obstack);
286 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
287 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
288 gen_proto (*insn_ptr);
290 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
291 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
292 gen_proto (*insn_ptr);
294 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
295 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
296 gen_nonproto (*insn_ptr);
298 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
299 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
300 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
301 gen_nonproto (*insn_ptr);
303 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
304 gen_nonproto (*insn_ptr);
306 printf ("#endif /* NO_MD_PROTOTYPES */\n");
309 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);