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 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. */
29 static struct obstack obstack
;
30 struct obstack
*rtl_obstack
= &obstack
;
32 #define obstack_chunk_alloc xmalloc
33 #define obstack_chunk_free free
35 extern rtx
read_rtx ();
40 void fatal
PVPROTO((char *, ...));
42 /* We must not provide any prototype here, even if ANSI C. */
48 /* Names for patterns. Need to allow linking with print-rtl. */
51 /* Obstacks to remember normal, and call insns. */
52 static struct obstack call_obstack
, normal_obstack
;
54 /* Max size of names encountered. */
55 static int max_id_len
;
57 /* Count the number of match_operand's found. */
65 enum rtx_code code
= GET_CODE (x
);
66 char *format_ptr
= GET_RTX_FORMAT (code
);
68 if (code
== MATCH_OPERAND
)
71 if (code
== MATCH_OPERATOR
|| code
== MATCH_PARALLEL
)
74 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
76 switch (*format_ptr
++)
80 count
+= num_operands (XEXP (x
, i
));
84 if (XVEC (x
, i
) != NULL
)
85 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
86 count
+= num_operands (XVECEXP (x
, i
, j
));
95 /* Print out prototype information for a function. */
101 int num
= num_operands (insn
);
102 printf ("extern rtx gen_%-*s PROTO((", max_id_len
, XSTR (insn
, 0));
117 /* Print out a function declaration without a prototype. */
123 printf ("extern rtx gen_%s ();\n", XSTR (insn
, 0));
130 char *name
= XSTR (insn
, 0);
132 struct obstack
*obstack_ptr
;
135 /* Don't mention instructions whose names are the null string
136 or begin with '*'. They are in the machine description just
138 if (name
[0] == 0 || name
[0] == '*')
143 if (len
> max_id_len
)
146 printf ("#define HAVE_%s ", name
);
147 if (strlen (XSTR (insn
, 2)) == 0)
151 /* Write the macro definition, putting \'s at the end of each line,
154 for (p
= XSTR (insn
, 2); *p
; p
++)
164 /* Save the current insn, so that we can later put out appropriate
165 prototypes. At present, most md files have the wrong number of
166 arguments for the call insns (call, call_value, call_pop,
167 call_value_pop) ignoring the extra arguments that are passed for
168 some machines, so by default, turn off the prototype. */
170 obstack_ptr
= (name
[0] == 'c'
171 && (!strcmp (name
, "call")
172 || !strcmp (name
, "call_value")
173 || !strcmp (name
, "call_pop")
174 || !strcmp (name
, "call_value_pop")))
175 ? &call_obstack
: &normal_obstack
;
177 obstack_grow (obstack_ptr
, &insn
, sizeof (rtx
));
184 register char *val
= (char *) malloc (size
);
187 fatal ("virtual memory exhausted");
197 char *result
= (char *) realloc (ptr
, size
);
199 fatal ("virtual memory exhausted");
206 fatal
VPROTO((char *s
, ...))
208 #ifndef ANSI_PROTOTYPES
215 #ifndef ANSI_PROTOTYPES
216 s
= va_arg (ap
, char *);
219 fprintf (stderr
, "genflags: ");
220 vfprintf (stderr
, s
, ap
);
222 fprintf (stderr
, "\n");
223 exit (FATAL_EXIT_CODE
);
225 #else /* not HAVE_VPRINTF */
231 fprintf (stderr
, "genflags: ");
232 fprintf (stderr
, s
, a1
, a2
);
233 fprintf (stderr
, "\n");
234 exit (FATAL_EXIT_CODE
);
236 #endif /* not HAVE_VPRINTF */
238 /* More 'friendly' abort that prints the line and file.
239 config.h can #define abort fancy_abort if you like that sort of thing. */
244 fatal ("Internal gcc abort.");
260 obstack_init (rtl_obstack
);
261 obstack_init (&call_obstack
);
262 obstack_init (&normal_obstack
);
265 fatal ("No input file name.");
267 infile
= fopen (argv
[1], "r");
271 exit (FATAL_EXIT_CODE
);
276 printf ("/* Generated automatically by the program `genflags'\n\
277 from the machine description file `md'. */\n\n");
279 /* Read the machine description. */
283 c
= read_skip_spaces (infile
);
288 desc
= read_rtx (infile
);
289 if (GET_CODE (desc
) == DEFINE_INSN
|| GET_CODE (desc
) == DEFINE_EXPAND
)
293 /* Print out the prototypes now. */
295 obstack_grow (&call_obstack
, &dummy
, sizeof (rtx
));
296 call_insns
= (rtx
*) obstack_finish (&call_obstack
);
298 obstack_grow (&normal_obstack
, &dummy
, sizeof (rtx
));
299 normal_insns
= (rtx
*) obstack_finish (&normal_obstack
);
301 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
302 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
303 gen_proto (*insn_ptr
);
305 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
306 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
307 gen_proto (*insn_ptr
);
309 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
310 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
311 gen_nonproto (*insn_ptr
);
313 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
314 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
315 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
316 gen_nonproto (*insn_ptr
);
318 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
319 gen_nonproto (*insn_ptr
);
321 printf ("#endif /* NO_MD_PROTOTYPES */\n");
324 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);