]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genflags.c
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
[thirdparty/gcc.git] / gcc / genflags.c
CommitLineData
3439974c 1/* Generate from machine description:
3439974c 2 - some flags HAVE_... saying which simple standard instructions are
3 available for this machine.
2f791da8 4 Copyright (C) 1987, 1991, 1995, 1998,
5 1999, 2000 Free Software Foundation, Inc.
3439974c 6
f12b58b3 7This file is part of GCC.
3439974c 8
f12b58b3 9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 2, or (at your option) any later
12version.
3439974c 13
f12b58b3 14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
3439974c 18
19You should have received a copy of the GNU General Public License
f12b58b3 20along with GCC; see the file COPYING. If not, write to the Free
21Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2202111-1307, USA. */
3439974c 23
24
550effbd 25#include "hconfig.h"
5ce88198 26#include "system.h"
3439974c 27#include "rtl.h"
28#include "obstack.h"
04b58880 29#include "errors.h"
c5ddd6b5 30#include "gensupport.h"
3439974c 31
3439974c 32
33#define obstack_chunk_alloc xmalloc
34#define obstack_chunk_free free
35
2ed6c343 36/* Obstack to remember insns with. */
37static struct obstack obstack;
fb084c16 38
39/* Max size of names encountered. */
40static int max_id_len;
41
0d2d46ac 42/* Max operand encountered in a scan over some insn. */
43static int max_opno;
12693c81 44
0d2d46ac 45static void max_operand_1 PARAMS ((rtx));
46static int num_operands PARAMS ((rtx));
47static void gen_proto PARAMS ((rtx));
2ed6c343 48static void gen_macro PARAMS ((const char *, int, int));
0d2d46ac 49static void gen_insn PARAMS ((rtx));
12693c81 50
fb084c16 51/* Count the number of match_operand's found. */
a92771b8 52
0d2d46ac 53static void
54max_operand_1 (x)
fb084c16 55 rtx x;
56{
0d2d46ac 57 register RTX_CODE code;
58 register int i;
59 register int len;
60 register const char *fmt;
fb084c16 61
0d2d46ac 62 if (x == 0)
63 return;
fb084c16 64
0d2d46ac 65 code = GET_CODE (x);
fb084c16 66
0d2d46ac 67 if (code == MATCH_OPERAND || code == MATCH_OPERATOR
68 || code == MATCH_PARALLEL)
69 max_opno = MAX (max_opno, XINT (x, 0));
70
71 fmt = GET_RTX_FORMAT (code);
72 len = GET_RTX_LENGTH (code);
73 for (i = 0; i < len; i++)
fb084c16 74 {
0d2d46ac 75 if (fmt[i] == 'e' || fmt[i] == 'u')
76 max_operand_1 (XEXP (x, i));
77 else if (fmt[i] == 'E')
fb084c16 78 {
0d2d46ac 79 int j;
80 for (j = 0; j < XVECLEN (x, i); j++)
81 max_operand_1 (XVECEXP (x, i, j));
fb084c16 82 }
83 }
0d2d46ac 84}
fb084c16 85
0d2d46ac 86static int
87num_operands (insn)
88 rtx insn;
89{
90 register int len = XVECLEN (insn, 1);
91 register int i;
92
93 max_opno = -1;
94
95 for (i = 0; i < len; i++)
96 max_operand_1 (XVECEXP (insn, 1, i));
97
98 return max_opno + 1;
fb084c16 99}
100
2ed6c343 101/* Print out a wrapper macro for a function which corrects the number
102 of arguments it takes. Any missing arguments are assumed to be at
103 the end. */
104static void
105gen_macro (name, real, expect)
106 const char *name;
107 int real, expect;
108{
109 int i;
110
111 if (real > expect)
112 abort ();
113 if (real == 0)
114 abort ();
115
116 /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
117 fputs ("#define GEN_", stdout);
118 for (i = 0; name[i]; i++)
119 putchar (TOUPPER (name[i]));
120
121 putchar('(');
122 for (i = 0; i < expect - 1; i++)
123 printf ("%c, ", i + 'A');
124 printf ("%c) gen_%s (", i + 'A', name);
125
126 for (i = 0; i < real - 1; i++)
127 printf ("(%c), ", i + 'A');
128 printf ("(%c))\n", i + 'A');
129}
130
fb084c16 131/* Print out prototype information for a function. */
a92771b8 132
fb084c16 133static void
134gen_proto (insn)
135 rtx insn;
136{
137 int num = num_operands (insn);
2ed6c343 138 const char *name = XSTR (insn, 0);
139
140 /* Many md files don't refer to the last two operands passed to the
141 call patterns. This means their generator functions will be two
142 arguments too short. Instead of changing every md file to touch
143 those operands, we wrap the prototypes in macros that take the
144 correct number of arguments. */
145 if (name[0] == 'c' || name[0] == 's')
146 {
147 if (!strcmp (name, "call")
148 || !strcmp (name, "call_pop")
149 || !strcmp (name, "sibcall")
150 || !strcmp (name, "sibcall_pop"))
151 gen_macro (name, num, 4);
152 else if (!strcmp (name, "call_value")
153 || !strcmp (name, "call_value_pop")
154 || !strcmp (name, "sibcall_value")
155 || !strcmp (name, "sibcall_value_pop"))
156 gen_macro (name, num, 5);
157 }
158
5645dcc7 159 printf ("extern struct rtx_def *gen_%-*s PARAMS ((", max_id_len, name);
fb084c16 160
161 if (num == 0)
162 printf ("void");
163 else
164 {
165 while (num-- > 1)
5645dcc7 166 printf ("struct rtx_def *, ");
fb084c16 167
5645dcc7 168 printf ("struct rtx_def *");
fb084c16 169 }
170
171 printf ("));\n");
fb084c16 172
fb084c16 173}
174
3439974c 175static void
176gen_insn (insn)
177 rtx insn;
178{
9a356c3c 179 const char *name = XSTR (insn, 0);
180 const char *p;
fb084c16 181 int len;
3439974c 182
a0761610 183 /* Don't mention instructions whose names are the null string
184 or begin with '*'. They are in the machine description just
185 to be recognized. */
186 if (name[0] == 0 || name[0] == '*')
3439974c 187 return;
188
a0761610 189 len = strlen (name);
190
fb084c16 191 if (len > max_id_len)
192 max_id_len = len;
193
194 printf ("#define HAVE_%s ", name);
3439974c 195 if (strlen (XSTR (insn, 2)) == 0)
196 printf ("1\n");
197 else
198 {
199 /* Write the macro definition, putting \'s at the end of each line,
200 if more than one. */
201 printf ("(");
202 for (p = XSTR (insn, 2); *p; p++)
203 {
204 if (*p == '\n')
205 printf (" \\\n");
206 else
207 printf ("%c", *p);
208 }
209 printf (")\n");
210 }
5ba9164e 211
2ed6c343 212 obstack_grow (&obstack, &insn, sizeof (rtx));
3439974c 213}
3439974c 214
929efc7f 215extern int main PARAMS ((int, char **));
947491b7 216
3439974c 217int
218main (argc, argv)
219 int argc;
220 char **argv;
221{
222 rtx desc;
fb084c16 223 rtx dummy;
2ed6c343 224 rtx *insns;
fb084c16 225 rtx *insn_ptr;
3439974c 226
04b58880 227 progname = "genflags";
2ed6c343 228 obstack_init (&obstack);
3439974c 229
230 if (argc <= 1)
231 fatal ("No input file name.");
232
c5ddd6b5 233 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
234 return (FATAL_EXIT_CODE);
235
d0c809e1 236 puts ("/* Generated automatically by the program `genflags'");
237 puts (" from the machine description file `md'. */\n");
238 puts ("#ifndef GCC_INSN_FLAGS_H");
239 puts ("#define GCC_INSN_FLAGS_H\n");
3439974c 240
241 /* Read the machine description. */
242
243 while (1)
244 {
c5ddd6b5 245 int line_no, insn_code_number = 0;
3439974c 246
c5ddd6b5 247 desc = read_md_rtx (&line_no, &insn_code_number);
248 if (desc == NULL)
249 break;
3439974c 250 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
251 gen_insn (desc);
252 }
253
fb084c16 254 /* Print out the prototypes now. */
a92771b8 255 dummy = (rtx) 0;
2ed6c343 256 obstack_grow (&obstack, &dummy, sizeof (rtx));
257 insns = (rtx *) obstack_finish (&obstack);
fb084c16 258
5645dcc7 259 printf ("struct rtx_def;\n");
2ed6c343 260 for (insn_ptr = insns; *insn_ptr; insn_ptr++)
fb084c16 261 gen_proto (*insn_ptr);
262
d0c809e1 263 puts("\n#endif /* GCC_INSN_FLAGS_H */");
264
265 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
266 return FATAL_EXIT_CODE;
267
268 return SUCCESS_EXIT_CODE;
3439974c 269}
6357eaae 270
271/* Define this so we can link with print-rtl.o to get debug_rtx function. */
272const char *
273get_insn_name (code)
947491b7 274 int code ATTRIBUTE_UNUSED;
6357eaae 275{
276 return NULL;
277}