]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
alias.c (rtx_equal_for_memref_p): Use predicates to test rtx classes and new rtx...
[thirdparty/gcc.git] / gcc / genopinit.c
CommitLineData
af9e4a0c 1/* Generate code to initialize optabs from machine description.
b5e01d4b 2 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
d9221e01 3 2001, 2002, 2003, 2004 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
4977bab6 23#include "bconfig.h"
0b93b64e 24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
af9e4a0c 27#include "rtl.h"
f8b6598e 28#include "errors.h"
c88c0d42 29#include "gensupport.h"
ccd043a9 30
af9e4a0c 31
af9e4a0c
RK
32/* Many parts of GCC use arrays that are indexed by machine mode and
33 contain the insn codes for pattern in the MD file that perform a given
34 operation on operands of that mode.
35
36 These patterns are present in the MD file with names that contain
37 the mode(s) used and the name of the operation. This program
38 writes a function `init_all_optabs' that initializes the optabs with
39 all the insn codes of the relevant patterns present in the MD file.
40
41 This array contains a list of optabs that need to be initialized. Within
42 each string, the name of the pattern to be matched against is delimited
1b3459d2 43 with $( and $). In the string, $a and $b are used to match a short mode
af9e4a0c
RK
44 name (the part of the mode name not including `mode' and converted to
45 lower-case). When writing out the initializer, the entire string is
1b3459d2 46 used. $A and $B are replaced with the full name of the mode; $a and $b
af9e4a0c
RK
47 are replaced with the short form of the name, as above.
48
1b3459d2
ZW
49 If $N is present in the pattern, it means the two modes must be consecutive
50 widths in the same mode class (e.g, QImode and HImode). $I means that
91ce572a
CC
51 only full integer modes should be considered for the next mode, and $F
52 means that only float modes should be considered.
53 $P means that both full and partial integer modes should be considered.
54
55 $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
af9e4a0c
RK
56
57 For some optabs, we store the operation by RTL codes. These are only
1b3459d2 58 used for comparisons. In that case, $c and $C are the lower-case and
af9e4a0c
RK
59 upper-case forms of the comparison, respectively. */
60
83182544 61static const char * const optabs[] =
85363ca0
ZW
62{ "sext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(extend$a$b2$)",
63 "zext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(zero_extend$a$b2$)",
64 "sfix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix$F$a$I$b2$)",
65 "ufix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns$F$a$b2$)",
66 "sfixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
67 "ufixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
68 "sfloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(float$I$a$F$b2$)",
69 "ufloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(floatuns$I$a$F$b2$)",
70 "trunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(trunc$a$b2$)",
91ce572a 71 "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
85363ca0
ZW
72 "addv_optab->handlers[$A].insn_code =\n\
73 add_optab->handlers[$A].insn_code = CODE_FOR_$(add$F$a3$)",
74 "addv_optab->handlers[$A].insn_code = CODE_FOR_$(addv$I$a3$)",
91ce572a 75 "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
85363ca0
ZW
76 "subv_optab->handlers[$A].insn_code =\n\
77 sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$F$a3$)",
78 "subv_optab->handlers[$A].insn_code = CODE_FOR_$(subv$I$a3$)",
91ce572a 79 "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
85363ca0
ZW
80 "smulv_optab->handlers[$A].insn_code =\n\
81 smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$F$a3$)",
82 "smulv_optab->handlers[$A].insn_code = CODE_FOR_$(mulv$I$a3$)",
1b3459d2
ZW
83 "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
84 "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
85 "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
86 "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
ef89d648 87 "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
85363ca0 88 "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
1b3459d2
ZW
89 "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
90 "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
91 "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
92 "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
93 "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
1b3459d2
ZW
94 "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
95 "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
96 "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
97 "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
98 "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
99 "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
100 "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
101 "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
102 "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
103 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$I$a3$)",
104 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(min$F$a3$)",
105 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$I$a3$)",
106 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
107 "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
108 "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
b5e01d4b
RS
109 "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
110 "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
91ce572a 111 "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
85363ca0
ZW
112 "negv_optab->handlers[$A].insn_code =\n\
113 neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
114 "negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
91ce572a 115 "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
85363ca0
ZW
116 "absv_optab->handlers[$A].insn_code =\n\
117 abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
118 "absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
1b3459d2 119 "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
4977bab6
ZW
120 "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
121 "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
122 "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
123 "trunc_optab->handlers[$A].insn_code = CODE_FOR_$(trunc$a2$)",
124 "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
1b3459d2
ZW
125 "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
126 "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
e7b489c8
RS
127 "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
128 "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
3b8e0c91
UB
129 "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",
130 "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",
82d397c7
RS
131 "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
132 "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
1b3459d2
ZW
133 "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
134 "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
135 "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
2928cd7a
RH
136 "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
137 "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
138 "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
139 "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
1b3459d2
ZW
140 "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
141 "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
142 "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
143 "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
068f5dea 144 "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
1b3459d2
ZW
145 "bcc_gen_fctn[$C] = gen_$(b$c$)",
146 "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
147 "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
148 "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
149 "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
150 "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
371b8fc0 151 "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
1b3459d2
ZW
152 "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
153 "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
154 "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
118355a0
ZW
155 "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)",
156 "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
997404de
JH
157 "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
158 "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
159 "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
160 "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)" };
af9e4a0c 161
3d7aafde 162static void gen_insn (rtx);
56c0e996 163
af9e4a0c 164static void
3d7aafde 165gen_insn (rtx insn)
af9e4a0c 166{
3cce094d 167 const char *name = XSTR (insn, 0);
a544cfd2 168 int m1 = 0, m2 = 0, op = 0;
5ae9a7e9 169 size_t pindex;
af9e4a0c 170 int i;
85fda1eb 171 const char *np, *pp, *p, *q;
af9e4a0c
RK
172
173 /* Don't mention instructions whose names are the null string.
174 They are in the machine description just to be recognized. */
175 if (*name == 0)
176 return;
177
178 /* See if NAME matches one of the patterns we have for the optabs we know
179 about. */
180
b6a1cbae 181 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
af9e4a0c 182 {
91ce572a 183 int force_float = 0, force_int = 0, force_partial_int = 0;
af9e4a0c
RK
184 int force_consec = 0;
185 int matches = 1;
186
1b3459d2 187 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
af9e4a0c
RK
188 ;
189
1b3459d2 190 for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
af9e4a0c
RK
191 pp++)
192 {
1b3459d2 193 if (*pp != '$')
af9e4a0c
RK
194 {
195 if (*pp != *np++)
196 break;
197 }
198 else
199 switch (*++pp)
200 {
201 case 'N':
202 force_consec = 1;
203 break;
204 case 'I':
205 force_int = 1;
206 break;
91ce572a
CC
207 case 'P':
208 force_partial_int = 1;
209 break;
af9e4a0c
RK
210 case 'F':
211 force_float = 1;
212 break;
91ce572a
CC
213 case 'V':
214 break;
af9e4a0c
RK
215 case 'c':
216 for (op = 0; op < NUM_RTX_CODE; op++)
217 {
5f06c983 218 for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
af9e4a0c
RK
219 if (*p != *q)
220 break;
221
222 /* We have to be concerned about matching "gt" and
223 missing "gtu", e.g., so verify we have reached the
4639555c 224 end of thing we are to match. */
ec8e098d
PB
225 if (*p == 0 && *q == 0
226 && (GET_RTX_CLASS (op) == RTX_COMPARE
227 || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
af9e4a0c
RK
228 break;
229 }
230
231 if (op == NUM_RTX_CODE)
232 matches = 0;
233 else
5f06c983 234 np += strlen (GET_RTX_NAME(op));
af9e4a0c
RK
235 break;
236 case 'a':
237 case 'b':
4639555c
ILT
238 /* This loop will stop at the first prefix match, so
239 look through the modes in reverse order, in case
94134f42 240 there are extra CC modes and CC is a prefix of the
4639555c 241 CC modes (as it should be). */
85363ca0 242 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
af9e4a0c 243 {
a4ec8d12 244 for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
92a438d1 245 if (TOLOWER (*p) != *q)
af9e4a0c
RK
246 break;
247
248 if (*p == 0
7d9e680f
DB
249 && (! force_int || mode_class[i] == MODE_INT
250 || mode_class[i] == MODE_VECTOR_INT)
91ce572a
CC
251 && (! force_partial_int
252 || mode_class[i] == MODE_INT
7d9e680f
DB
253 || mode_class[i] == MODE_PARTIAL_INT
254 || mode_class[i] == MODE_VECTOR_INT)
255 && (! force_float || mode_class[i] == MODE_FLOAT
256 || mode_class[i] == MODE_VECTOR_FLOAT))
af9e4a0c
RK
257 break;
258 }
259
4639555c 260 if (i < 0)
af9e4a0c
RK
261 matches = 0;
262 else if (*pp == 'a')
a4ec8d12 263 m1 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 264 else
a4ec8d12 265 m2 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 266
91ce572a 267 force_int = force_partial_int = force_float = 0;
af9e4a0c
RK
268 break;
269
270 default:
271 abort ();
272 }
273 }
274
1b3459d2 275 if (matches && pp[0] == '$' && pp[1] == ')'
af9e4a0c 276 && *np == 0
88a5e9da 277 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
af9e4a0c
RK
278 break;
279 }
280
b6a1cbae 281 if (pindex == ARRAY_SIZE (optabs))
af9e4a0c
RK
282 return;
283
284 /* We found a match. If this pattern is only conditionally present,
285 write out the "if" and two extra blanks. */
286
287 if (*XSTR (insn, 2) != 0)
288 printf (" if (HAVE_%s)\n ", name);
289
290 printf (" ");
291
292 /* Now write out the initialization, making all required substitutions. */
293 for (pp = optabs[pindex]; *pp; pp++)
294 {
1b3459d2
ZW
295 if (*pp != '$')
296 putchar (*pp);
af9e4a0c
RK
297 else
298 switch (*++pp)
299 {
300 case '(': case ')':
301 case 'I': case 'F': case 'N':
302 break;
91ce572a
CC
303 case 'V':
304 if (GET_MODE_CLASS (m1) == MODE_FLOAT)
305 printf ("v");
306 break;
af9e4a0c 307 case 'a':
a4ec8d12 308 for (np = GET_MODE_NAME(m1); *np; np++)
92a438d1 309 putchar (TOLOWER (*np));
af9e4a0c
RK
310 break;
311 case 'b':
a4ec8d12 312 for (np = GET_MODE_NAME(m2); *np; np++)
92a438d1 313 putchar (TOLOWER (*np));
af9e4a0c
RK
314 break;
315 case 'A':
85363ca0 316 printf ("%smode", GET_MODE_NAME(m1));
af9e4a0c
RK
317 break;
318 case 'B':
85363ca0 319 printf ("%smode", GET_MODE_NAME(m2));
af9e4a0c
RK
320 break;
321 case 'c':
5f06c983 322 printf ("%s", GET_RTX_NAME(op));
af9e4a0c
RK
323 break;
324 case 'C':
5f06c983 325 for (np = GET_RTX_NAME(op); *np; np++)
92a438d1 326 putchar (TOUPPER (*np));
af9e4a0c
RK
327 break;
328 }
329 }
330
331 printf (";\n");
332}
af9e4a0c 333
3d7aafde 334extern int main (int, char **);
c1b59dce 335
af9e4a0c 336int
3d7aafde 337main (int argc, char **argv)
af9e4a0c
RK
338{
339 rtx desc;
af9e4a0c 340
f8b6598e 341 progname = "genopinit";
af9e4a0c
RK
342
343 if (argc <= 1)
1f978f5f 344 fatal ("no input file name");
af9e4a0c 345
04d8aa70 346 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 347 return (FATAL_EXIT_CODE);
af9e4a0c 348
af9e4a0c
RK
349 printf ("/* Generated automatically by the program `genopinit'\n\
350from the machine description file `md'. */\n\n");
351
352 printf ("#include \"config.h\"\n");
729da3f5 353 printf ("#include \"system.h\"\n");
4977bab6
ZW
354 printf ("#include \"coretypes.h\"\n");
355 printf ("#include \"tm.h\"\n");
af9e4a0c
RK
356 printf ("#include \"rtl.h\"\n");
357 printf ("#include \"flags.h\"\n");
af9e4a0c
RK
358 printf ("#include \"insn-config.h\"\n");
359 printf ("#include \"recog.h\"\n");
360 printf ("#include \"expr.h\"\n");
e78d8e51 361 printf ("#include \"optabs.h\"\n");
af9e4a0c
RK
362 printf ("#include \"reload.h\"\n\n");
363
6906ba40 364 printf ("void\ninit_all_optabs (void)\n{\n");
af9e4a0c 365
dcc3fcf2
KH
366 puts ("\
367#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
368 int i, j;\n\
369#endif\n");
370
af9e4a0c
RK
371 /* Read the machine description. */
372
373 while (1)
374 {
c88c0d42
CP
375 int line_no, insn_code_number = 0;
376
377 desc = read_md_rtx (&line_no, &insn_code_number);
378 if (desc == NULL)
af9e4a0c 379 break;
af9e4a0c 380
af9e4a0c
RK
381 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
382 gen_insn (desc);
383 }
384
85363ca0
ZW
385 puts ("\
386\n\
387#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
388 /* This flag says the same insns that convert to a signed fixnum\n\
389 also convert validly to an unsigned one. */\n\
390 for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
391 for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
392 ufixtrunc_optab->handlers[i][j].insn_code\n\
393 = sfixtrunc_optab->handlers[i][j].insn_code;\n\
394#endif\n\
395}");
af9e4a0c
RK
396
397 fflush (stdout);
c1b59dce 398 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
af9e4a0c 399}
a995e389
RH
400
401/* Define this so we can link with print-rtl.o to get debug_rtx function. */
402const char *
3d7aafde 403get_insn_name (int code ATTRIBUTE_UNUSED)
a995e389
RH
404{
405 return NULL;
406}