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,
5 1999, 2000 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. */
31 static struct obstack obstack
;
32 struct obstack
*rtl_obstack
= &obstack
;
34 #define obstack_chunk_alloc xmalloc
35 #define obstack_chunk_free free
37 /* Obstacks to remember normal, and call insns. */
38 static struct obstack call_obstack
, normal_obstack
;
40 /* Max size of names encountered. */
41 static int max_id_len
;
43 /* Max operand encountered in a scan over some insn. */
46 static void max_operand_1
PARAMS ((rtx
));
47 static int num_operands
PARAMS ((rtx
));
48 static void gen_proto
PARAMS ((rtx
));
49 static void gen_nonproto
PARAMS ((rtx
));
50 static void gen_insn
PARAMS ((rtx
));
52 /* Count the number of match_operand's found. */
58 register RTX_CODE code
;
61 register const char *fmt
;
68 if (code
== MATCH_OPERAND
|| code
== MATCH_OPERATOR
69 || code
== MATCH_PARALLEL
)
70 max_opno
= MAX (max_opno
, XINT (x
, 0));
72 fmt
= GET_RTX_FORMAT (code
);
73 len
= GET_RTX_LENGTH (code
);
74 for (i
= 0; i
< len
; i
++)
76 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
77 max_operand_1 (XEXP (x
, i
));
78 else if (fmt
[i
] == 'E')
81 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
82 max_operand_1 (XVECEXP (x
, i
, j
));
91 register int len
= XVECLEN (insn
, 1);
96 for (i
= 0; i
< len
; i
++)
97 max_operand_1 (XVECEXP (insn
, 1, i
));
102 /* Print out prototype information for a function. */
108 int num
= num_operands (insn
);
109 printf ("extern rtx gen_%-*s PARAMS ((", max_id_len
, XSTR (insn
, 0));
124 /* Print out a function declaration without a prototype. */
130 printf ("extern rtx gen_%s ();\n", XSTR (insn
, 0));
137 const char *name
= XSTR (insn
, 0);
139 struct obstack
*obstack_ptr
;
142 /* Don't mention instructions whose names are the null string
143 or begin with '*'. They are in the machine description just
145 if (name
[0] == 0 || name
[0] == '*')
150 if (len
> max_id_len
)
153 printf ("#define HAVE_%s ", name
);
154 if (strlen (XSTR (insn
, 2)) == 0)
158 /* Write the macro definition, putting \'s at the end of each line,
161 for (p
= XSTR (insn
, 2); *p
; p
++)
171 /* Save the current insn, so that we can later put out appropriate
172 prototypes. At present, most md files have the wrong number of
173 arguments for the call insns (call, call_value, call_pop,
174 call_value_pop) ignoring the extra arguments that are passed for
175 some machines, so by default, turn off the prototype. */
177 obstack_ptr
= ((name
[0] == 'c' || name
[0] == 's')
178 && (!strcmp (name
, "call")
179 || !strcmp (name
, "call_value")
180 || !strcmp (name
, "call_pop")
181 || !strcmp (name
, "call_value_pop")
182 || !strcmp (name
, "sibcall")
183 || !strcmp (name
, "sibcall_value")
184 || !strcmp (name
, "sibcall_pop")
185 || !strcmp (name
, "sibcall_value_pop")))
186 ? &call_obstack
: &normal_obstack
;
188 obstack_grow (obstack_ptr
, &insn
, sizeof (rtx
));
195 register PTR val
= (PTR
) malloc (size
);
198 fatal ("virtual memory exhausted");
210 ptr
= (PTR
) realloc (old
, size
);
212 ptr
= (PTR
) malloc (size
);
214 fatal ("virtual memory exhausted");
218 extern int main
PARAMS ((int, char **));
233 progname
= "genflags";
234 obstack_init (rtl_obstack
);
235 obstack_init (&call_obstack
);
236 obstack_init (&normal_obstack
);
239 fatal ("No input file name.");
241 infile
= fopen (argv
[1], "r");
245 return (FATAL_EXIT_CODE
);
247 read_rtx_filename
= argv
[1];
249 printf ("/* Generated automatically by the program `genflags'\n\
250 from the machine description file `md'. */\n\n");
252 /* Read the machine description. */
256 c
= read_skip_spaces (infile
);
261 desc
= read_rtx (infile
);
262 if (GET_CODE (desc
) == DEFINE_INSN
|| GET_CODE (desc
) == DEFINE_EXPAND
)
266 /* Print out the prototypes now. */
268 obstack_grow (&call_obstack
, &dummy
, sizeof (rtx
));
269 call_insns
= (rtx
*) obstack_finish (&call_obstack
);
271 obstack_grow (&normal_obstack
, &dummy
, sizeof (rtx
));
272 normal_insns
= (rtx
*) obstack_finish (&normal_obstack
);
274 for (insn_ptr
= normal_insns
; *insn_ptr
; insn_ptr
++)
275 gen_proto (*insn_ptr
);
277 printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
278 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
279 gen_proto (*insn_ptr
);
281 printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
282 for (insn_ptr
= call_insns
; *insn_ptr
; insn_ptr
++)
283 gen_nonproto (*insn_ptr
);
285 printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
288 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
291 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
294 int code ATTRIBUTE_UNUSED
;