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 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 static struct obstack obstack
;
30 struct obstack
*rtl_obstack
= &obstack
;
32 #define obstack_chunk_alloc xmalloc
33 #define obstack_chunk_free free
36 extern rtx
read_rtx ();
42 /* Names for patterns. Need to allow linking with print-rtl. */
45 /* Obstacks to remember normal, and call insns. */
46 static struct obstack call_obstack
, normal_obstack
;
48 /* Max size of names encountered. */
49 static int max_id_len
;
51 /* Count the number of match_operand's found. */
58 enum rtx_code code
= GET_CODE (x
);
59 char *format_ptr
= GET_RTX_FORMAT (code
);
61 if (code
== MATCH_OPERAND
)
64 if (code
== MATCH_OPERATOR
|| code
== MATCH_PARALLEL
)
67 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
69 switch (*format_ptr
++)
73 count
+= num_operands (XEXP (x
, i
));
77 if (XVEC (x
, i
) != NULL
)
78 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
79 count
+= num_operands (XVECEXP (x
, i
, j
));
88 /* Print out prototype information for a function. */
93 int num
= num_operands (insn
);
94 printf ("extern rtx gen_%-*s PROTO((", max_id_len
, XSTR (insn
, 0));
109 /* Print out a function declaration without a prototype. */
114 printf ("extern rtx gen_%s ();\n", XSTR (insn
, 0));
121 char *name
= XSTR (insn
, 0);
123 struct obstack
*obstack_ptr
;
126 /* Don't mention instructions whose names are the null string.
127 They are in the machine description just to be recognized. */
132 if (len
> max_id_len
)
135 printf ("#define HAVE_%s ", name
);
136 if (strlen (XSTR (insn
, 2)) == 0)
140 /* Write the macro definition, putting \'s at the end of each line,
143 for (p
= XSTR (insn
, 2); *p
; p
++)
153 /* Save the current insn, so that we can later put out appropriate
154 prototypes. At present, most md files have the wrong number of
155 arguments for the call insns (call, call_value, call_pop,
156 call_value_pop) ignoring the extra arguments that are passed for
157 some machines, so by default, turn off the prototype. */
159 obstack_ptr
= (name
[0] == 'c'
160 && (!strcmp (name
, "call")
161 || !strcmp (name
, "call_value")
162 || !strcmp (name
, "call_pop")
163 || !strcmp (name
, "call_value_pop")))
164 ? &call_obstack
: &normal_obstack
;
166 obstack_grow (obstack_ptr
, &insn
, sizeof (rtx
));
173 register char *val
= (char *) malloc (size
);
176 fatal ("virtual memory exhausted");
186 char *result
= (char *) realloc (ptr
, size
);
188 fatal ("virtual memory exhausted");
196 fprintf (stderr
, "genflags: ");
197 fprintf (stderr
, s
, a1
, a2
);
198 fprintf (stderr
, "\n");
199 exit (FATAL_EXIT_CODE
);
202 /* More 'friendly' abort that prints the line and file.
203 config.h can #define abort fancy_abort if you like that sort of thing. */
208 fatal ("Internal gcc abort.");
224 obstack_init (rtl_obstack
);
225 obstack_init (&call_obstack
);
226 obstack_init (&normal_obstack
);
229 fatal ("No input file name.");
231 infile
= fopen (argv
[1], "r");
235 exit (FATAL_EXIT_CODE
);
240 printf ("/* Generated automatically by the program `genflags'\n\
241 from the machine description file `md'. */\n\n");
243 /* Read the machine description. */
247 c
= read_skip_spaces (infile
);
252 desc
= read_rtx (infile
);
253 if (GET_CODE (desc
) == DEFINE_INSN
|| GET_CODE (desc
) == DEFINE_EXPAND
)
257 /* Print out the prototypes now. */
259 obstack_grow (&call_obstack
, &dummy
, sizeof (rtx
));
260 call_insns
= (rtx
*) obstack_finish (&call_obstack
);
262 obstack_grow (&normal_obstack
, &dummy
, sizeof (rtx
));
263 normal_insns
= (rtx
*) obstack_finish (&normal_obstack
);
265 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
266 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
267 gen_proto (*insn_ptr
);
269 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
270 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
271 gen_proto (*insn_ptr
);
273 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
274 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
275 gen_nonproto (*insn_ptr
);
277 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
278 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
279 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
280 gen_nonproto (*insn_ptr
);
282 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
283 gen_nonproto (*insn_ptr
);
285 printf ("#endif /* NO_MD_PROTOTYPES */\n");
288 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);