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. */
35 static struct obstack obstack;
36 struct obstack *rtl_obstack = &obstack;
38 #define obstack_chunk_alloc xmalloc
39 #define obstack_chunk_free free
41 char *xmalloc PROTO((unsigned));
42 static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
43 void fancy_abort PROTO((void));
45 /* Names for patterns. Need to allow linking with print-rtl. */
48 /* Obstacks to remember normal, and call insns. */
49 static struct obstack call_obstack, normal_obstack;
51 /* Max size of names encountered. */
52 static int max_id_len;
54 static int num_operands PROTO((rtx));
55 static void gen_proto PROTO((rtx));
56 static void gen_nonproto PROTO((rtx));
57 static void gen_insn PROTO((rtx));
60 /* Count the number of match_operand's found. */
68 enum rtx_code code = GET_CODE (x);
69 char *format_ptr = GET_RTX_FORMAT (code);
71 if (code == MATCH_OPERAND)
74 if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
77 for (i = 0; i < GET_RTX_LENGTH (code); i++)
79 switch (*format_ptr++)
83 count += num_operands (XEXP (x, i));
87 if (XVEC (x, i) != NULL)
88 for (j = 0; j < XVECLEN (x, i); j++)
89 count += num_operands (XVECEXP (x, i, j));
98 /* Print out prototype information for a function. */
104 int num = num_operands (insn);
105 printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
120 /* Print out a function declaration without a prototype. */
126 printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
133 char *name = XSTR (insn, 0);
135 struct obstack *obstack_ptr;
138 /* Don't mention instructions whose names are the null string
139 or begin with '*'. They are in the machine description just
141 if (name[0] == 0 || name[0] == '*')
146 if (len > max_id_len)
149 printf ("#define HAVE_%s ", name);
150 if (strlen (XSTR (insn, 2)) == 0)
154 /* Write the macro definition, putting \'s at the end of each line,
157 for (p = XSTR (insn, 2); *p; p++)
167 /* Save the current insn, so that we can later put out appropriate
168 prototypes. At present, most md files have the wrong number of
169 arguments for the call insns (call, call_value, call_pop,
170 call_value_pop) ignoring the extra arguments that are passed for
171 some machines, so by default, turn off the prototype. */
173 obstack_ptr = (name[0] == 'c'
174 && (!strcmp (name, "call")
175 || !strcmp (name, "call_value")
176 || !strcmp (name, "call_pop")
177 || !strcmp (name, "call_value_pop")))
178 ? &call_obstack : &normal_obstack;
180 obstack_grow (obstack_ptr, &insn, sizeof (rtx));
187 register char *val = (char *) malloc (size);
190 fatal ("virtual memory exhausted");
200 char *result = (char *) realloc (ptr, size);
202 fatal ("virtual memory exhausted");
207 fatal VPROTO ((char *format, ...))
214 VA_START (ap, format);
217 format = va_arg (ap, char *);
220 fprintf (stderr, "genflags: ");
221 vfprintf (stderr, format, ap);
223 fprintf (stderr, "\n");
224 exit (FATAL_EXIT_CODE);
227 /* More 'friendly' abort that prints the line and file.
228 config.h can #define abort fancy_abort if you like that sort of thing. */
233 fatal ("Internal gcc abort.");
249 obstack_init (rtl_obstack);
250 obstack_init (&call_obstack);
251 obstack_init (&normal_obstack);
254 fatal ("No input file name.");
256 infile = fopen (argv[1], "r");
260 exit (FATAL_EXIT_CODE);
265 printf ("/* Generated automatically by the program `genflags'\n\
266 from the machine description file `md'. */\n\n");
268 /* Read the machine description. */
272 c = read_skip_spaces (infile);
277 desc = read_rtx (infile);
278 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
282 /* Print out the prototypes now. */
284 obstack_grow (&call_obstack, &dummy, sizeof (rtx));
285 call_insns = (rtx *) obstack_finish (&call_obstack);
287 obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
288 normal_insns = (rtx *) obstack_finish (&normal_obstack);
290 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
291 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
292 gen_proto (*insn_ptr);
294 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
295 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
296 gen_proto (*insn_ptr);
298 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
299 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
300 gen_nonproto (*insn_ptr);
302 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
303 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
304 for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
305 gen_nonproto (*insn_ptr);
307 for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
308 gen_nonproto (*insn_ptr);
310 printf ("#endif /* NO_MD_PROTOTYPES */\n");
313 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);