]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
explow.c (int_expr_size): New fn.
[thirdparty/gcc.git] / gcc / genopinit.c
CommitLineData
af9e4a0c 1/* Generate code to initialize optabs from machine description.
d050d723
JL
2 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
af9e4a0c 4
1322177d 5This file is part of GCC.
af9e4a0c 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
af9e4a0c 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
af9e4a0c
RK
16
17You should have received a copy of the GNU General Public License
1322177d
LB
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
af9e4a0c
RK
21
22
af9e4a0c 23#include "hconfig.h"
0b93b64e 24#include "system.h"
af9e4a0c 25#include "rtl.h"
f8b6598e 26#include "errors.h"
c88c0d42 27#include "gensupport.h"
ccd043a9 28
af9e4a0c 29
af9e4a0c
RK
30/* Many parts of GCC use arrays that are indexed by machine mode and
31 contain the insn codes for pattern in the MD file that perform a given
32 operation on operands of that mode.
33
34 These patterns are present in the MD file with names that contain
35 the mode(s) used and the name of the operation. This program
36 writes a function `init_all_optabs' that initializes the optabs with
37 all the insn codes of the relevant patterns present in the MD file.
38
39 This array contains a list of optabs that need to be initialized. Within
40 each string, the name of the pattern to be matched against is delimited
1b3459d2 41 with $( and $). In the string, $a and $b are used to match a short mode
af9e4a0c
RK
42 name (the part of the mode name not including `mode' and converted to
43 lower-case). When writing out the initializer, the entire string is
1b3459d2 44 used. $A and $B are replaced with the full name of the mode; $a and $b
af9e4a0c
RK
45 are replaced with the short form of the name, as above.
46
1b3459d2
ZW
47 If $N is present in the pattern, it means the two modes must be consecutive
48 widths in the same mode class (e.g, QImode and HImode). $I means that
91ce572a
CC
49 only full integer modes should be considered for the next mode, and $F
50 means that only float modes should be considered.
51 $P means that both full and partial integer modes should be considered.
52
53 $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
af9e4a0c
RK
54
55 For some optabs, we store the operation by RTL codes. These are only
1b3459d2 56 used for comparisons. In that case, $c and $C are the lower-case and
af9e4a0c
RK
57 upper-case forms of the comparison, respectively. */
58
83182544 59static const char * const optabs[] =
1b3459d2
ZW
60{ "extendtab[$B][$A][0] = CODE_FOR_$(extend$a$b2$)",
61 "extendtab[$B][$A][1] = CODE_FOR_$(zero_extend$a$b2$)",
62 "fixtab[$A][$B][0] = CODE_FOR_$(fix$F$a$I$b2$)",
63 "fixtab[$A][$B][1] = CODE_FOR_$(fixuns$F$a$b2$)",
64 "fixtrunctab[$A][$B][0] = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
65 "fixtrunctab[$A][$B][1] = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
66 "floattab[$B][$A][0] = CODE_FOR_$(float$I$a$F$b2$)",
67 "floattab[$B][$A][1] = CODE_FOR_$(floatuns$I$a$F$b2$)",
91ce572a
CC
68 "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
69 "addv_optab->handlers[(int) $A].insn_code =\n\
70 add_optab->handlers[(int) $A].insn_code = CODE_FOR_$(add$F$a3$)",
71 "addv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(addv$I$a3$)",
72 "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
73 "subv_optab->handlers[(int) $A].insn_code =\n\
74 sub_optab->handlers[(int) $A].insn_code = CODE_FOR_$(sub$F$a3$)",
75 "subv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(subv$I$a3$)",
76 "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
77 "smulv_optab->handlers[(int) $A].insn_code =\n\
78 smul_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mul$F$a3$)",
79 "smulv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mulv$I$a3$)",
1b3459d2
ZW
80 "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
81 "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
82 "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
83 "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
ef89d648 84 "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
91ce572a 85 "sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)",
1b3459d2
ZW
86 "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
87 "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
88 "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
89 "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
90 "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
1b3459d2
ZW
91 "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
92 "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
93 "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
94 "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
95 "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
96 "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
97 "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
98 "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
99 "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
100 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$I$a3$)",
101 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(min$F$a3$)",
102 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$I$a3$)",
103 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
104 "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
105 "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
91ce572a
CC
106 "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
107 "negv_optab->handlers[(int) $A].insn_code =\n\
108 neg_optab->handlers[(int) $A].insn_code = CODE_FOR_$(neg$F$a2$)",
109 "negv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(negv$I$a2$)",
110 "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
111 "absv_optab->handlers[(int) $A].insn_code =\n\
112 abs_optab->handlers[(int) $A].insn_code = CODE_FOR_$(abs$F$a2$)",
113 "absv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(absv$I$a2$)",
1b3459d2
ZW
114 "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
115 "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
116 "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
117 "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
118 "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
119 "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
120 "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
121 "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
122 "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
123 "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
124 "bcc_gen_fctn[$C] = gen_$(b$c$)",
125 "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
126 "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
127 "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
128 "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
129 "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
371b8fc0 130 "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
1b3459d2
ZW
131 "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
132 "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
133 "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
134 "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)" };
af9e4a0c 135
a94ae8f5 136static void gen_insn PARAMS ((rtx));
56c0e996 137
af9e4a0c
RK
138static void
139gen_insn (insn)
140 rtx insn;
141{
3cce094d 142 const char *name = XSTR (insn, 0);
a544cfd2 143 int m1 = 0, m2 = 0, op = 0;
5ae9a7e9 144 size_t pindex;
af9e4a0c 145 int i;
85fda1eb 146 const char *np, *pp, *p, *q;
af9e4a0c
RK
147
148 /* Don't mention instructions whose names are the null string.
149 They are in the machine description just to be recognized. */
150 if (*name == 0)
151 return;
152
153 /* See if NAME matches one of the patterns we have for the optabs we know
154 about. */
155
b6a1cbae 156 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
af9e4a0c 157 {
91ce572a 158 int force_float = 0, force_int = 0, force_partial_int = 0;
af9e4a0c
RK
159 int force_consec = 0;
160 int matches = 1;
161
1b3459d2 162 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
af9e4a0c
RK
163 ;
164
1b3459d2 165 for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
af9e4a0c
RK
166 pp++)
167 {
1b3459d2 168 if (*pp != '$')
af9e4a0c
RK
169 {
170 if (*pp != *np++)
171 break;
172 }
173 else
174 switch (*++pp)
175 {
176 case 'N':
177 force_consec = 1;
178 break;
179 case 'I':
180 force_int = 1;
181 break;
91ce572a
CC
182 case 'P':
183 force_partial_int = 1;
184 break;
af9e4a0c
RK
185 case 'F':
186 force_float = 1;
187 break;
91ce572a
CC
188 case 'V':
189 break;
af9e4a0c
RK
190 case 'c':
191 for (op = 0; op < NUM_RTX_CODE; op++)
192 {
5f06c983 193 for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
af9e4a0c
RK
194 if (*p != *q)
195 break;
196
197 /* We have to be concerned about matching "gt" and
198 missing "gtu", e.g., so verify we have reached the
4639555c 199 end of thing we are to match. */
1f9a015e 200 if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
af9e4a0c
RK
201 break;
202 }
203
204 if (op == NUM_RTX_CODE)
205 matches = 0;
206 else
5f06c983 207 np += strlen (GET_RTX_NAME(op));
af9e4a0c
RK
208 break;
209 case 'a':
210 case 'b':
4639555c
ILT
211 /* This loop will stop at the first prefix match, so
212 look through the modes in reverse order, in case
213 EXTRA_CC_MODES was used and CC is a prefix of the
214 CC modes (as it should be). */
215 for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
af9e4a0c 216 {
a4ec8d12 217 for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
92a438d1 218 if (TOLOWER (*p) != *q)
af9e4a0c
RK
219 break;
220
221 if (*p == 0
7d9e680f
DB
222 && (! force_int || mode_class[i] == MODE_INT
223 || mode_class[i] == MODE_VECTOR_INT)
91ce572a
CC
224 && (! force_partial_int
225 || mode_class[i] == MODE_INT
7d9e680f
DB
226 || mode_class[i] == MODE_PARTIAL_INT
227 || mode_class[i] == MODE_VECTOR_INT)
228 && (! force_float || mode_class[i] == MODE_FLOAT
229 || mode_class[i] == MODE_VECTOR_FLOAT))
af9e4a0c
RK
230 break;
231 }
232
4639555c 233 if (i < 0)
af9e4a0c
RK
234 matches = 0;
235 else if (*pp == 'a')
a4ec8d12 236 m1 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 237 else
a4ec8d12 238 m2 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 239
91ce572a 240 force_int = force_partial_int = force_float = 0;
af9e4a0c
RK
241 break;
242
243 default:
244 abort ();
245 }
246 }
247
1b3459d2 248 if (matches && pp[0] == '$' && pp[1] == ')'
af9e4a0c 249 && *np == 0
88a5e9da 250 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
af9e4a0c
RK
251 break;
252 }
253
b6a1cbae 254 if (pindex == ARRAY_SIZE (optabs))
af9e4a0c
RK
255 return;
256
257 /* We found a match. If this pattern is only conditionally present,
258 write out the "if" and two extra blanks. */
259
260 if (*XSTR (insn, 2) != 0)
261 printf (" if (HAVE_%s)\n ", name);
262
263 printf (" ");
264
265 /* Now write out the initialization, making all required substitutions. */
266 for (pp = optabs[pindex]; *pp; pp++)
267 {
1b3459d2
ZW
268 if (*pp != '$')
269 putchar (*pp);
af9e4a0c
RK
270 else
271 switch (*++pp)
272 {
273 case '(': case ')':
274 case 'I': case 'F': case 'N':
275 break;
91ce572a
CC
276 case 'V':
277 if (GET_MODE_CLASS (m1) == MODE_FLOAT)
278 printf ("v");
279 break;
af9e4a0c 280 case 'a':
a4ec8d12 281 for (np = GET_MODE_NAME(m1); *np; np++)
92a438d1 282 putchar (TOLOWER (*np));
af9e4a0c
RK
283 break;
284 case 'b':
a4ec8d12 285 for (np = GET_MODE_NAME(m2); *np; np++)
92a438d1 286 putchar (TOLOWER (*np));
af9e4a0c
RK
287 break;
288 case 'A':
1b3459d2 289 printf ("(int) %smode", GET_MODE_NAME(m1));
af9e4a0c
RK
290 break;
291 case 'B':
1b3459d2 292 printf ("(int) %smode", GET_MODE_NAME(m2));
af9e4a0c
RK
293 break;
294 case 'c':
5f06c983 295 printf ("%s", GET_RTX_NAME(op));
af9e4a0c
RK
296 break;
297 case 'C':
1b3459d2 298 printf ("(int) ");
5f06c983 299 for (np = GET_RTX_NAME(op); *np; np++)
92a438d1 300 putchar (TOUPPER (*np));
af9e4a0c
RK
301 break;
302 }
303 }
304
305 printf (";\n");
306}
af9e4a0c 307
a94ae8f5 308extern int main PARAMS ((int, char **));
c1b59dce 309
af9e4a0c
RK
310int
311main (argc, argv)
312 int argc;
313 char **argv;
314{
315 rtx desc;
af9e4a0c 316
f8b6598e 317 progname = "genopinit";
af9e4a0c
RK
318
319 if (argc <= 1)
1f978f5f 320 fatal ("no input file name");
af9e4a0c 321
04d8aa70 322 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 323 return (FATAL_EXIT_CODE);
af9e4a0c 324
af9e4a0c
RK
325 printf ("/* Generated automatically by the program `genopinit'\n\
326from the machine description file `md'. */\n\n");
327
328 printf ("#include \"config.h\"\n");
729da3f5 329 printf ("#include \"system.h\"\n");
af9e4a0c
RK
330 printf ("#include \"rtl.h\"\n");
331 printf ("#include \"flags.h\"\n");
af9e4a0c
RK
332 printf ("#include \"insn-config.h\"\n");
333 printf ("#include \"recog.h\"\n");
334 printf ("#include \"expr.h\"\n");
e78d8e51 335 printf ("#include \"optabs.h\"\n");
af9e4a0c
RK
336 printf ("#include \"reload.h\"\n\n");
337
338 printf ("void\ninit_all_optabs ()\n{\n");
339
340 /* Read the machine description. */
341
342 while (1)
343 {
c88c0d42
CP
344 int line_no, insn_code_number = 0;
345
346 desc = read_md_rtx (&line_no, &insn_code_number);
347 if (desc == NULL)
af9e4a0c 348 break;
af9e4a0c 349
af9e4a0c
RK
350 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
351 gen_insn (desc);
352 }
353
354 printf ("}\n");
355
356 fflush (stdout);
c1b59dce 357 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
af9e4a0c 358}
a995e389
RH
359
360/* Define this so we can link with print-rtl.o to get debug_rtx function. */
361const char *
362get_insn_name (code)
c1b59dce 363 int code ATTRIBUTE_UNUSED;
a995e389
RH
364{
365 return NULL;
366}