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. */
34 static struct obstack obstack
;
35 struct obstack
*rtl_obstack
= &obstack
;
37 #define obstack_chunk_alloc xmalloc
38 #define obstack_chunk_free free
40 #ifdef NEED_DECLARATION_FREE
43 extern rtx
read_rtx ();
49 /* Names for patterns. Need to allow linking with print-rtl. */
52 /* Obstacks to remember normal, and call insns. */
53 static struct obstack call_obstack
, normal_obstack
;
55 /* Max size of names encountered. */
56 static int max_id_len
;
58 /* Count the number of match_operand's found. */
66 enum rtx_code code
= GET_CODE (x
);
67 char *format_ptr
= GET_RTX_FORMAT (code
);
69 if (code
== MATCH_OPERAND
)
72 if (code
== MATCH_OPERATOR
|| code
== MATCH_PARALLEL
)
75 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
77 switch (*format_ptr
++)
81 count
+= num_operands (XEXP (x
, i
));
85 if (XVEC (x
, i
) != NULL
)
86 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
87 count
+= num_operands (XVECEXP (x
, i
, j
));
96 /* Print out prototype information for a function. */
102 int num
= num_operands (insn
);
103 printf ("extern rtx gen_%-*s PROTO((", max_id_len
, XSTR (insn
, 0));
118 /* Print out a function declaration without a prototype. */
124 printf ("extern rtx gen_%s ();\n", XSTR (insn
, 0));
131 char *name
= XSTR (insn
, 0);
133 struct obstack
*obstack_ptr
;
136 /* Don't mention instructions whose names are the null string
137 or begin with '*'. They are in the machine description just
139 if (name
[0] == 0 || name
[0] == '*')
144 if (len
> max_id_len
)
147 printf ("#define HAVE_%s ", name
);
148 if (strlen (XSTR (insn
, 2)) == 0)
152 /* Write the macro definition, putting \'s at the end of each line,
155 for (p
= XSTR (insn
, 2); *p
; p
++)
165 /* Save the current insn, so that we can later put out appropriate
166 prototypes. At present, most md files have the wrong number of
167 arguments for the call insns (call, call_value, call_pop,
168 call_value_pop) ignoring the extra arguments that are passed for
169 some machines, so by default, turn off the prototype. */
171 obstack_ptr
= (name
[0] == 'c'
172 && (!strcmp (name
, "call")
173 || !strcmp (name
, "call_value")
174 || !strcmp (name
, "call_pop")
175 || !strcmp (name
, "call_value_pop")))
176 ? &call_obstack
: &normal_obstack
;
178 obstack_grow (obstack_ptr
, &insn
, sizeof (rtx
));
185 register char *val
= (char *) malloc (size
);
188 fatal ("virtual memory exhausted");
198 char *result
= (char *) realloc (ptr
, size
);
200 fatal ("virtual memory exhausted");
208 fprintf (stderr
, "genflags: ");
209 fprintf (stderr
, s
, a1
, a2
);
210 fprintf (stderr
, "\n");
211 exit (FATAL_EXIT_CODE
);
214 /* More 'friendly' abort that prints the line and file.
215 config.h can #define abort fancy_abort if you like that sort of thing. */
220 fatal ("Internal gcc abort.");
236 obstack_init (rtl_obstack
);
237 obstack_init (&call_obstack
);
238 obstack_init (&normal_obstack
);
241 fatal ("No input file name.");
243 infile
= fopen (argv
[1], "r");
247 exit (FATAL_EXIT_CODE
);
252 printf ("/* Generated automatically by the program `genflags'\n\
253 from the machine description file `md'. */\n\n");
255 /* Read the machine description. */
259 c
= read_skip_spaces (infile
);
264 desc
= read_rtx (infile
);
265 if (GET_CODE (desc
) == DEFINE_INSN
|| GET_CODE (desc
) == DEFINE_EXPAND
)
269 /* Print out the prototypes now. */
271 obstack_grow (&call_obstack
, &dummy
, sizeof (rtx
));
272 call_insns
= (rtx
*) obstack_finish (&call_obstack
);
274 obstack_grow (&normal_obstack
, &dummy
, sizeof (rtx
));
275 normal_insns
= (rtx
*) obstack_finish (&normal_obstack
);
277 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
278 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
279 gen_proto (*insn_ptr
);
281 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
282 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
283 gen_proto (*insn_ptr
);
285 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
286 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
287 gen_nonproto (*insn_ptr
);
289 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
290 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
291 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
292 gen_nonproto (*insn_ptr
);
294 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
295 gen_nonproto (*insn_ptr
);
297 printf ("#endif /* NO_MD_PROTOTYPES */\n");
300 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);