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, 1999 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. */
30 static struct obstack obstack
;
31 struct obstack
*rtl_obstack
= &obstack
;
33 #define obstack_chunk_alloc xmalloc
34 #define obstack_chunk_free free
36 /* Obstacks to remember normal, and call insns. */
37 static struct obstack call_obstack
, normal_obstack
;
39 /* Max size of names encountered. */
40 static int max_id_len
;
42 static int num_operands
PROTO((rtx
));
43 static void gen_proto
PROTO((rtx
));
44 static void gen_nonproto
PROTO((rtx
));
45 static void gen_insn
PROTO((rtx
));
48 /* Count the number of match_operand's found. */
56 enum rtx_code code
= GET_CODE (x
);
57 const char *format_ptr
= GET_RTX_FORMAT (code
);
59 if (code
== MATCH_OPERAND
)
62 if (code
== MATCH_OPERATOR
|| code
== MATCH_PARALLEL
)
65 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
67 switch (*format_ptr
++)
71 count
+= num_operands (XEXP (x
, i
));
75 if (XVEC (x
, i
) != NULL
)
76 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
77 count
+= num_operands (XVECEXP (x
, i
, j
));
86 /* Print out prototype information for a function. */
92 int num
= num_operands (insn
);
93 printf ("extern rtx gen_%-*s PROTO((", max_id_len
, XSTR (insn
, 0));
108 /* 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 or begin with '*'. They are in the machine description just
129 if (name
[0] == 0 || name
[0] == '*')
134 if (len
> max_id_len
)
137 printf ("#define HAVE_%s ", name
);
138 if (strlen (XSTR (insn
, 2)) == 0)
142 /* Write the macro definition, putting \'s at the end of each line,
145 for (p
= XSTR (insn
, 2); *p
; p
++)
155 /* Save the current insn, so that we can later put out appropriate
156 prototypes. At present, most md files have the wrong number of
157 arguments for the call insns (call, call_value, call_pop,
158 call_value_pop) ignoring the extra arguments that are passed for
159 some machines, so by default, turn off the prototype. */
161 obstack_ptr
= (name
[0] == 'c'
162 && (!strcmp (name
, "call")
163 || !strcmp (name
, "call_value")
164 || !strcmp (name
, "call_pop")
165 || !strcmp (name
, "call_value_pop")))
166 ? &call_obstack
: &normal_obstack
;
168 obstack_grow (obstack_ptr
, &insn
, sizeof (rtx
));
175 register PTR val
= (PTR
) malloc (size
);
178 fatal ("virtual memory exhausted");
190 ptr
= (PTR
) realloc (old
, size
);
192 ptr
= (PTR
) malloc (size
);
194 fatal ("virtual memory exhausted");
198 extern int main
PROTO ((int, char **));
213 progname
= "genflags";
214 obstack_init (rtl_obstack
);
215 obstack_init (&call_obstack
);
216 obstack_init (&normal_obstack
);
219 fatal ("No input file name.");
221 infile
= fopen (argv
[1], "r");
225 return (FATAL_EXIT_CODE
);
228 printf ("/* Generated automatically by the program `genflags'\n\
229 from the machine description file `md'. */\n\n");
231 /* Read the machine description. */
235 c
= read_skip_spaces (infile
);
240 desc
= read_rtx (infile
);
241 if (GET_CODE (desc
) == DEFINE_INSN
|| GET_CODE (desc
) == DEFINE_EXPAND
)
245 /* Print out the prototypes now. */
247 obstack_grow (&call_obstack
, &dummy
, sizeof (rtx
));
248 call_insns
= (rtx
*) obstack_finish (&call_obstack
);
250 obstack_grow (&normal_obstack
, &dummy
, sizeof (rtx
));
251 normal_insns
= (rtx
*) obstack_finish (&normal_obstack
);
253 printf ("\n#ifndef NO_MD_PROTOTYPES\n");
254 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
255 gen_proto (*insn_ptr
);
257 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
258 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
259 gen_proto (*insn_ptr
);
261 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
262 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
263 gen_nonproto (*insn_ptr
);
265 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
266 printf ("\n#else /* NO_MD_PROTOTYPES */\n");
267 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
268 gen_nonproto (*insn_ptr
);
270 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
271 gen_nonproto (*insn_ptr
);
273 printf ("#endif /* NO_MD_PROTOTYPES */\n");
276 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
279 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
282 int code ATTRIBUTE_UNUSED
;