]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
Fix pathname in last delta.
[thirdparty/gcc.git] / gcc / genopinit.c
CommitLineData
af9e4a0c 1/* Generate code to initialize optabs from machine description.
b5e01d4b
RS
2 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 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$)",
82d397c7
RS
129 "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
130 "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
1b3459d2
ZW
131 "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
132 "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
133 "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
2928cd7a
RH
134 "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
135 "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
136 "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
137 "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
1b3459d2
ZW
138 "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
139 "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
140 "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
141 "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
068f5dea 142 "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
1b3459d2
ZW
143 "bcc_gen_fctn[$C] = gen_$(b$c$)",
144 "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
145 "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
146 "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
147 "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
148 "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
371b8fc0 149 "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
1b3459d2
ZW
150 "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
151 "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
152 "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
118355a0
ZW
153 "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)",
154 "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
155 "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)" };
af9e4a0c 156
3d7aafde 157static void gen_insn (rtx);
56c0e996 158
af9e4a0c 159static void
3d7aafde 160gen_insn (rtx insn)
af9e4a0c 161{
3cce094d 162 const char *name = XSTR (insn, 0);
a544cfd2 163 int m1 = 0, m2 = 0, op = 0;
5ae9a7e9 164 size_t pindex;
af9e4a0c 165 int i;
85fda1eb 166 const char *np, *pp, *p, *q;
af9e4a0c
RK
167
168 /* Don't mention instructions whose names are the null string.
169 They are in the machine description just to be recognized. */
170 if (*name == 0)
171 return;
172
173 /* See if NAME matches one of the patterns we have for the optabs we know
174 about. */
175
b6a1cbae 176 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
af9e4a0c 177 {
91ce572a 178 int force_float = 0, force_int = 0, force_partial_int = 0;
af9e4a0c
RK
179 int force_consec = 0;
180 int matches = 1;
181
1b3459d2 182 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
af9e4a0c
RK
183 ;
184
1b3459d2 185 for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
af9e4a0c
RK
186 pp++)
187 {
1b3459d2 188 if (*pp != '$')
af9e4a0c
RK
189 {
190 if (*pp != *np++)
191 break;
192 }
193 else
194 switch (*++pp)
195 {
196 case 'N':
197 force_consec = 1;
198 break;
199 case 'I':
200 force_int = 1;
201 break;
91ce572a
CC
202 case 'P':
203 force_partial_int = 1;
204 break;
af9e4a0c
RK
205 case 'F':
206 force_float = 1;
207 break;
91ce572a
CC
208 case 'V':
209 break;
af9e4a0c
RK
210 case 'c':
211 for (op = 0; op < NUM_RTX_CODE; op++)
212 {
5f06c983 213 for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
af9e4a0c
RK
214 if (*p != *q)
215 break;
216
217 /* We have to be concerned about matching "gt" and
218 missing "gtu", e.g., so verify we have reached the
4639555c 219 end of thing we are to match. */
1f9a015e 220 if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
af9e4a0c
RK
221 break;
222 }
223
224 if (op == NUM_RTX_CODE)
225 matches = 0;
226 else
5f06c983 227 np += strlen (GET_RTX_NAME(op));
af9e4a0c
RK
228 break;
229 case 'a':
230 case 'b':
4639555c
ILT
231 /* This loop will stop at the first prefix match, so
232 look through the modes in reverse order, in case
233 EXTRA_CC_MODES was used and CC is a prefix of the
234 CC modes (as it should be). */
85363ca0 235 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
af9e4a0c 236 {
a4ec8d12 237 for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
92a438d1 238 if (TOLOWER (*p) != *q)
af9e4a0c
RK
239 break;
240
241 if (*p == 0
7d9e680f
DB
242 && (! force_int || mode_class[i] == MODE_INT
243 || mode_class[i] == MODE_VECTOR_INT)
91ce572a
CC
244 && (! force_partial_int
245 || mode_class[i] == MODE_INT
7d9e680f
DB
246 || mode_class[i] == MODE_PARTIAL_INT
247 || mode_class[i] == MODE_VECTOR_INT)
248 && (! force_float || mode_class[i] == MODE_FLOAT
249 || mode_class[i] == MODE_VECTOR_FLOAT))
af9e4a0c
RK
250 break;
251 }
252
4639555c 253 if (i < 0)
af9e4a0c
RK
254 matches = 0;
255 else if (*pp == 'a')
a4ec8d12 256 m1 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 257 else
a4ec8d12 258 m2 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 259
91ce572a 260 force_int = force_partial_int = force_float = 0;
af9e4a0c
RK
261 break;
262
263 default:
264 abort ();
265 }
266 }
267
1b3459d2 268 if (matches && pp[0] == '$' && pp[1] == ')'
af9e4a0c 269 && *np == 0
88a5e9da 270 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
af9e4a0c
RK
271 break;
272 }
273
b6a1cbae 274 if (pindex == ARRAY_SIZE (optabs))
af9e4a0c
RK
275 return;
276
277 /* We found a match. If this pattern is only conditionally present,
278 write out the "if" and two extra blanks. */
279
280 if (*XSTR (insn, 2) != 0)
281 printf (" if (HAVE_%s)\n ", name);
282
283 printf (" ");
284
285 /* Now write out the initialization, making all required substitutions. */
286 for (pp = optabs[pindex]; *pp; pp++)
287 {
1b3459d2
ZW
288 if (*pp != '$')
289 putchar (*pp);
af9e4a0c
RK
290 else
291 switch (*++pp)
292 {
293 case '(': case ')':
294 case 'I': case 'F': case 'N':
295 break;
91ce572a
CC
296 case 'V':
297 if (GET_MODE_CLASS (m1) == MODE_FLOAT)
298 printf ("v");
299 break;
af9e4a0c 300 case 'a':
a4ec8d12 301 for (np = GET_MODE_NAME(m1); *np; np++)
92a438d1 302 putchar (TOLOWER (*np));
af9e4a0c
RK
303 break;
304 case 'b':
a4ec8d12 305 for (np = GET_MODE_NAME(m2); *np; np++)
92a438d1 306 putchar (TOLOWER (*np));
af9e4a0c
RK
307 break;
308 case 'A':
85363ca0 309 printf ("%smode", GET_MODE_NAME(m1));
af9e4a0c
RK
310 break;
311 case 'B':
85363ca0 312 printf ("%smode", GET_MODE_NAME(m2));
af9e4a0c
RK
313 break;
314 case 'c':
5f06c983 315 printf ("%s", GET_RTX_NAME(op));
af9e4a0c
RK
316 break;
317 case 'C':
5f06c983 318 for (np = GET_RTX_NAME(op); *np; np++)
92a438d1 319 putchar (TOUPPER (*np));
af9e4a0c
RK
320 break;
321 }
322 }
323
324 printf (";\n");
325}
af9e4a0c 326
3d7aafde 327extern int main (int, char **);
c1b59dce 328
af9e4a0c 329int
3d7aafde 330main (int argc, char **argv)
af9e4a0c
RK
331{
332 rtx desc;
af9e4a0c 333
f8b6598e 334 progname = "genopinit";
af9e4a0c
RK
335
336 if (argc <= 1)
1f978f5f 337 fatal ("no input file name");
af9e4a0c 338
04d8aa70 339 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 340 return (FATAL_EXIT_CODE);
af9e4a0c 341
af9e4a0c
RK
342 printf ("/* Generated automatically by the program `genopinit'\n\
343from the machine description file `md'. */\n\n");
344
345 printf ("#include \"config.h\"\n");
729da3f5 346 printf ("#include \"system.h\"\n");
4977bab6
ZW
347 printf ("#include \"coretypes.h\"\n");
348 printf ("#include \"tm.h\"\n");
af9e4a0c
RK
349 printf ("#include \"rtl.h\"\n");
350 printf ("#include \"flags.h\"\n");
af9e4a0c
RK
351 printf ("#include \"insn-config.h\"\n");
352 printf ("#include \"recog.h\"\n");
353 printf ("#include \"expr.h\"\n");
e78d8e51 354 printf ("#include \"optabs.h\"\n");
af9e4a0c
RK
355 printf ("#include \"reload.h\"\n\n");
356
6906ba40 357 printf ("void\ninit_all_optabs (void)\n{\n");
af9e4a0c
RK
358
359 /* Read the machine description. */
360
361 while (1)
362 {
c88c0d42
CP
363 int line_no, insn_code_number = 0;
364
365 desc = read_md_rtx (&line_no, &insn_code_number);
366 if (desc == NULL)
af9e4a0c 367 break;
af9e4a0c 368
af9e4a0c
RK
369 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
370 gen_insn (desc);
371 }
372
85363ca0
ZW
373 puts ("\
374\n\
375#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
376 /* This flag says the same insns that convert to a signed fixnum\n\
377 also convert validly to an unsigned one. */\n\
378 for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
379 for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
380 ufixtrunc_optab->handlers[i][j].insn_code\n\
381 = sfixtrunc_optab->handlers[i][j].insn_code;\n\
382#endif\n\
383}");
af9e4a0c
RK
384
385 fflush (stdout);
c1b59dce 386 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
af9e4a0c 387}
a995e389
RH
388
389/* Define this so we can link with print-rtl.o to get debug_rtx function. */
390const char *
3d7aafde 391get_insn_name (int code ATTRIBUTE_UNUSED)
a995e389
RH
392{
393 return NULL;
394}