Mercurial > hg > CbC > CbC_gcc
annotate gcc/genflags.c @ 56:3c8a44c06a95
Added tag gcc-4.4.5 for changeset 77e2b8dfacca
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:41:23 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
rev | line source |
---|---|
0 | 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, 2000, 2003, 2004, 2007 | |
5 Free Software Foundation, Inc. | |
6 | |
7 This file is part of GCC. | |
8 | |
9 GCC is free software; you can redistribute it and/or modify it under | |
10 the terms of the GNU General Public License as published by the Free | |
11 Software Foundation; either version 3, or (at your option) any later | |
12 version. | |
13 | |
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with GCC; see the file COPYING3. If not see | |
21 <http://www.gnu.org/licenses/>. */ | |
22 | |
23 | |
24 #include "bconfig.h" | |
25 #include "system.h" | |
26 #include "coretypes.h" | |
27 #include "tm.h" | |
28 #include "rtl.h" | |
29 #include "obstack.h" | |
30 #include "errors.h" | |
31 #include "gensupport.h" | |
32 | |
33 /* Obstack to remember insns with. */ | |
34 static struct obstack obstack; | |
35 | |
36 /* Max size of names encountered. */ | |
37 static int max_id_len; | |
38 | |
39 /* Max operand encountered in a scan over some insn. */ | |
40 static int max_opno; | |
41 | |
42 static void max_operand_1 (rtx); | |
43 static int num_operands (rtx); | |
44 static void gen_proto (rtx); | |
45 static void gen_macro (const char *, int, int); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
46 static void gen_insn (int, rtx); |
0 | 47 |
48 /* Count the number of match_operand's found. */ | |
49 | |
50 static void | |
51 max_operand_1 (rtx x) | |
52 { | |
53 RTX_CODE code; | |
54 int i; | |
55 int len; | |
56 const char *fmt; | |
57 | |
58 if (x == 0) | |
59 return; | |
60 | |
61 code = GET_CODE (x); | |
62 | |
63 if (code == MATCH_OPERAND || code == MATCH_OPERATOR | |
64 || code == MATCH_PARALLEL) | |
65 max_opno = MAX (max_opno, XINT (x, 0)); | |
66 | |
67 fmt = GET_RTX_FORMAT (code); | |
68 len = GET_RTX_LENGTH (code); | |
69 for (i = 0; i < len; i++) | |
70 { | |
71 if (fmt[i] == 'e' || fmt[i] == 'u') | |
72 max_operand_1 (XEXP (x, i)); | |
73 else if (fmt[i] == 'E') | |
74 { | |
75 int j; | |
76 for (j = 0; j < XVECLEN (x, i); j++) | |
77 max_operand_1 (XVECEXP (x, i, j)); | |
78 } | |
79 } | |
80 } | |
81 | |
82 static int | |
83 num_operands (rtx insn) | |
84 { | |
85 int len = XVECLEN (insn, 1); | |
86 int i; | |
87 | |
88 max_opno = -1; | |
89 | |
90 for (i = 0; i < len; i++) | |
91 max_operand_1 (XVECEXP (insn, 1, i)); | |
92 | |
93 return max_opno + 1; | |
94 } | |
95 | |
96 /* Print out a wrapper macro for a function which corrects the number | |
97 of arguments it takes. Any missing arguments are assumed to be at | |
98 the end. */ | |
99 static void | |
100 gen_macro (const char *name, int real, int expect) | |
101 { | |
102 int i; | |
103 | |
104 gcc_assert (real <= expect); | |
105 gcc_assert (real); | |
106 | |
107 /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */ | |
108 fputs ("#define GEN_", stdout); | |
109 for (i = 0; name[i]; i++) | |
110 putchar (TOUPPER (name[i])); | |
111 | |
112 putchar('('); | |
113 for (i = 0; i < expect - 1; i++) | |
114 printf ("%c, ", i + 'A'); | |
115 printf ("%c) gen_%s (", i + 'A', name); | |
116 | |
117 for (i = 0; i < real - 1; i++) | |
118 printf ("(%c), ", i + 'A'); | |
119 printf ("(%c))\n", i + 'A'); | |
120 } | |
121 | |
122 /* Print out prototype information for a generator function. If the | |
123 insn pattern has been elided, print out a dummy generator that | |
124 does nothing. */ | |
125 | |
126 static void | |
127 gen_proto (rtx insn) | |
128 { | |
129 int num = num_operands (insn); | |
130 int i; | |
131 const char *name = XSTR (insn, 0); | |
132 int truth = maybe_eval_c_test (XSTR (insn, 2)); | |
133 | |
134 /* Many md files don't refer to the last two operands passed to the | |
135 call patterns. This means their generator functions will be two | |
136 arguments too short. Instead of changing every md file to touch | |
137 those operands, we wrap the prototypes in macros that take the | |
138 correct number of arguments. */ | |
139 if (name[0] == 'c' || name[0] == 's') | |
140 { | |
141 if (!strcmp (name, "call") | |
142 || !strcmp (name, "call_pop") | |
143 || !strcmp (name, "sibcall") | |
144 || !strcmp (name, "sibcall_pop")) | |
145 gen_macro (name, num, 4); | |
146 else if (!strcmp (name, "call_value") | |
147 || !strcmp (name, "call_value_pop") | |
148 || !strcmp (name, "sibcall_value") | |
149 || !strcmp (name, "sibcall_value_pop")) | |
150 gen_macro (name, num, 5); | |
151 } | |
152 | |
153 if (truth != 0) | |
154 printf ("extern rtx gen_%-*s (", max_id_len, name); | |
155 else | |
156 printf ("static inline rtx gen_%-*s (", max_id_len, name); | |
157 | |
158 if (num == 0) | |
159 fputs ("void", stdout); | |
160 else | |
161 { | |
162 for (i = 1; i < num; i++) | |
163 fputs ("rtx, ", stdout); | |
164 | |
165 fputs ("rtx", stdout); | |
166 } | |
167 | |
168 puts (");"); | |
169 | |
170 /* Some back ends want to take the address of generator functions, | |
171 so we cannot simply use #define for these dummy definitions. */ | |
172 if (truth == 0) | |
173 { | |
174 printf ("static inline rtx\ngen_%s", name); | |
175 if (num > 0) | |
176 { | |
177 putchar ('('); | |
178 for (i = 0; i < num-1; i++) | |
179 printf ("rtx ARG_UNUSED (%c), ", 'a' + i); | |
180 printf ("rtx ARG_UNUSED (%c))\n", 'a' + i); | |
181 } | |
182 else | |
183 puts ("(void)"); | |
184 puts ("{\n return 0;\n}"); | |
185 } | |
186 | |
187 } | |
188 | |
189 static void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
190 gen_insn (int line_no, rtx insn) |
0 | 191 { |
192 const char *name = XSTR (insn, 0); | |
193 const char *p; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
194 const char *lt, *gt; |
0 | 195 int len; |
196 int truth = maybe_eval_c_test (XSTR (insn, 2)); | |
197 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
198 lt = strchr (name, '<'); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
199 if (lt && strchr (lt + 1, '>')) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
200 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
201 message_with_line (line_no, "unresolved iterator"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
202 have_error = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
203 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
204 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
205 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
206 gt = strchr (name, '>'); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
207 if (lt || gt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
208 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
209 message_with_line (line_no, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
210 "unmatched angle brackets, likely " |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
211 "an error in iterator syntax"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
212 have_error = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
213 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
214 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
215 |
0 | 216 /* Don't mention instructions whose names are the null string |
217 or begin with '*'. They are in the machine description just | |
218 to be recognized. */ | |
219 if (name[0] == 0 || name[0] == '*') | |
220 return; | |
221 | |
222 len = strlen (name); | |
223 | |
224 if (len > max_id_len) | |
225 max_id_len = len; | |
226 | |
227 if (truth == 0) | |
228 /* Emit nothing. */; | |
229 else if (truth == 1) | |
230 printf ("#define HAVE_%s 1\n", name); | |
231 else | |
232 { | |
233 /* Write the macro definition, putting \'s at the end of each line, | |
234 if more than one. */ | |
235 printf ("#define HAVE_%s (", name); | |
236 for (p = XSTR (insn, 2); *p; p++) | |
237 { | |
238 if (IS_VSPACE (*p)) | |
239 fputs (" \\\n", stdout); | |
240 else | |
241 putchar (*p); | |
242 } | |
243 fputs (")\n", stdout); | |
244 } | |
245 | |
246 obstack_grow (&obstack, &insn, sizeof (rtx)); | |
247 } | |
248 | |
249 int | |
250 main (int argc, char **argv) | |
251 { | |
252 rtx desc; | |
253 rtx dummy; | |
254 rtx *insns; | |
255 rtx *insn_ptr; | |
256 | |
257 progname = "genflags"; | |
258 obstack_init (&obstack); | |
259 | |
260 /* We need to see all the possibilities. Elided insns may have | |
261 direct calls to their generators in C code. */ | |
262 insn_elision = 0; | |
263 | |
264 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) | |
265 return (FATAL_EXIT_CODE); | |
266 | |
267 puts ("/* Generated automatically by the program `genflags'"); | |
268 puts (" from the machine description file `md'. */\n"); | |
269 puts ("#ifndef GCC_INSN_FLAGS_H"); | |
270 puts ("#define GCC_INSN_FLAGS_H\n"); | |
271 | |
272 /* Read the machine description. */ | |
273 | |
274 while (1) | |
275 { | |
276 int line_no, insn_code_number = 0; | |
277 | |
278 desc = read_md_rtx (&line_no, &insn_code_number); | |
279 if (desc == NULL) | |
280 break; | |
281 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
282 gen_insn (line_no, desc); |
0 | 283 } |
284 | |
285 /* Print out the prototypes now. */ | |
286 dummy = (rtx) 0; | |
287 obstack_grow (&obstack, &dummy, sizeof (rtx)); | |
288 insns = XOBFINISH (&obstack, rtx *); | |
289 | |
290 for (insn_ptr = insns; *insn_ptr; insn_ptr++) | |
291 gen_proto (*insn_ptr); | |
292 | |
293 puts("\n#endif /* GCC_INSN_FLAGS_H */"); | |
294 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
295 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout)) |
0 | 296 return FATAL_EXIT_CODE; |
297 | |
298 return SUCCESS_EXIT_CODE; | |
299 } |