]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
Daily bump.
[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[] =
1b3459d2
ZW
62{ "extendtab[$B][$A][0] = CODE_FOR_$(extend$a$b2$)",
63 "extendtab[$B][$A][1] = CODE_FOR_$(zero_extend$a$b2$)",
64 "fixtab[$A][$B][0] = CODE_FOR_$(fix$F$a$I$b2$)",
65 "fixtab[$A][$B][1] = CODE_FOR_$(fixuns$F$a$b2$)",
66 "fixtrunctab[$A][$B][0] = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
67 "fixtrunctab[$A][$B][1] = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
68 "floattab[$B][$A][0] = CODE_FOR_$(float$I$a$F$b2$)",
69 "floattab[$B][$A][1] = CODE_FOR_$(floatuns$I$a$F$b2$)",
91ce572a
CC
70 "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
71 "addv_optab->handlers[(int) $A].insn_code =\n\
72 add_optab->handlers[(int) $A].insn_code = CODE_FOR_$(add$F$a3$)",
73 "addv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(addv$I$a3$)",
74 "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
75 "subv_optab->handlers[(int) $A].insn_code =\n\
76 sub_optab->handlers[(int) $A].insn_code = CODE_FOR_$(sub$F$a3$)",
77 "subv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(subv$I$a3$)",
78 "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
79 "smulv_optab->handlers[(int) $A].insn_code =\n\
80 smul_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mul$F$a3$)",
81 "smulv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mulv$I$a3$)",
1b3459d2
ZW
82 "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
83 "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
84 "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
85 "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
ef89d648 86 "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
91ce572a 87 "sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)",
1b3459d2
ZW
88 "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
89 "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
90 "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
91 "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
92 "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
1b3459d2
ZW
93 "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
94 "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
95 "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
96 "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
97 "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
98 "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
99 "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
100 "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
101 "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
102 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$I$a3$)",
103 "smin_optab->handlers[$A].insn_code = CODE_FOR_$(min$F$a3$)",
104 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$I$a3$)",
105 "smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
106 "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
107 "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
b5e01d4b
RS
108 "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
109 "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
91ce572a
CC
110 "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
111 "negv_optab->handlers[(int) $A].insn_code =\n\
112 neg_optab->handlers[(int) $A].insn_code = CODE_FOR_$(neg$F$a2$)",
113 "negv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(negv$I$a2$)",
114 "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
115 "absv_optab->handlers[(int) $A].insn_code =\n\
116 abs_optab->handlers[(int) $A].insn_code = CODE_FOR_$(abs$F$a2$)",
117 "absv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(absv$I$a2$)",
1b3459d2 118 "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
4977bab6
ZW
119 "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
120 "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
121 "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
122 "trunc_optab->handlers[$A].insn_code = CODE_FOR_$(trunc$a2$)",
123 "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
1b3459d2
ZW
124 "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
125 "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
e7b489c8
RS
126 "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
127 "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
82d397c7
RS
128 "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
129 "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
1b3459d2
ZW
130 "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
131 "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
132 "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
2928cd7a
RH
133 "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
134 "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
135 "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
136 "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
1b3459d2
ZW
137 "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
138 "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
139 "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
140 "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
068f5dea 141 "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
1b3459d2
ZW
142 "bcc_gen_fctn[$C] = gen_$(b$c$)",
143 "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
144 "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
145 "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
146 "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
147 "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
371b8fc0 148 "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
1b3459d2
ZW
149 "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
150 "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
151 "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
152 "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)" };
af9e4a0c 153
3d7aafde 154static void gen_insn (rtx);
56c0e996 155
af9e4a0c 156static void
3d7aafde 157gen_insn (rtx insn)
af9e4a0c 158{
3cce094d 159 const char *name = XSTR (insn, 0);
a544cfd2 160 int m1 = 0, m2 = 0, op = 0;
5ae9a7e9 161 size_t pindex;
af9e4a0c 162 int i;
85fda1eb 163 const char *np, *pp, *p, *q;
af9e4a0c
RK
164
165 /* Don't mention instructions whose names are the null string.
166 They are in the machine description just to be recognized. */
167 if (*name == 0)
168 return;
169
170 /* See if NAME matches one of the patterns we have for the optabs we know
171 about. */
172
b6a1cbae 173 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
af9e4a0c 174 {
91ce572a 175 int force_float = 0, force_int = 0, force_partial_int = 0;
af9e4a0c
RK
176 int force_consec = 0;
177 int matches = 1;
178
1b3459d2 179 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
af9e4a0c
RK
180 ;
181
1b3459d2 182 for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
af9e4a0c
RK
183 pp++)
184 {
1b3459d2 185 if (*pp != '$')
af9e4a0c
RK
186 {
187 if (*pp != *np++)
188 break;
189 }
190 else
191 switch (*++pp)
192 {
193 case 'N':
194 force_consec = 1;
195 break;
196 case 'I':
197 force_int = 1;
198 break;
91ce572a
CC
199 case 'P':
200 force_partial_int = 1;
201 break;
af9e4a0c
RK
202 case 'F':
203 force_float = 1;
204 break;
91ce572a
CC
205 case 'V':
206 break;
af9e4a0c
RK
207 case 'c':
208 for (op = 0; op < NUM_RTX_CODE; op++)
209 {
5f06c983 210 for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
af9e4a0c
RK
211 if (*p != *q)
212 break;
213
214 /* We have to be concerned about matching "gt" and
215 missing "gtu", e.g., so verify we have reached the
4639555c 216 end of thing we are to match. */
1f9a015e 217 if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
af9e4a0c
RK
218 break;
219 }
220
221 if (op == NUM_RTX_CODE)
222 matches = 0;
223 else
5f06c983 224 np += strlen (GET_RTX_NAME(op));
af9e4a0c
RK
225 break;
226 case 'a':
227 case 'b':
4639555c
ILT
228 /* This loop will stop at the first prefix match, so
229 look through the modes in reverse order, in case
230 EXTRA_CC_MODES was used and CC is a prefix of the
231 CC modes (as it should be). */
232 for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
af9e4a0c 233 {
a4ec8d12 234 for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
92a438d1 235 if (TOLOWER (*p) != *q)
af9e4a0c
RK
236 break;
237
238 if (*p == 0
7d9e680f
DB
239 && (! force_int || mode_class[i] == MODE_INT
240 || mode_class[i] == MODE_VECTOR_INT)
91ce572a
CC
241 && (! force_partial_int
242 || mode_class[i] == MODE_INT
7d9e680f
DB
243 || mode_class[i] == MODE_PARTIAL_INT
244 || mode_class[i] == MODE_VECTOR_INT)
245 && (! force_float || mode_class[i] == MODE_FLOAT
246 || mode_class[i] == MODE_VECTOR_FLOAT))
af9e4a0c
RK
247 break;
248 }
249
4639555c 250 if (i < 0)
af9e4a0c
RK
251 matches = 0;
252 else if (*pp == 'a')
a4ec8d12 253 m1 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 254 else
a4ec8d12 255 m2 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 256
91ce572a 257 force_int = force_partial_int = force_float = 0;
af9e4a0c
RK
258 break;
259
260 default:
261 abort ();
262 }
263 }
264
1b3459d2 265 if (matches && pp[0] == '$' && pp[1] == ')'
af9e4a0c 266 && *np == 0
88a5e9da 267 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
af9e4a0c
RK
268 break;
269 }
270
b6a1cbae 271 if (pindex == ARRAY_SIZE (optabs))
af9e4a0c
RK
272 return;
273
274 /* We found a match. If this pattern is only conditionally present,
275 write out the "if" and two extra blanks. */
276
277 if (*XSTR (insn, 2) != 0)
278 printf (" if (HAVE_%s)\n ", name);
279
280 printf (" ");
281
282 /* Now write out the initialization, making all required substitutions. */
283 for (pp = optabs[pindex]; *pp; pp++)
284 {
1b3459d2
ZW
285 if (*pp != '$')
286 putchar (*pp);
af9e4a0c
RK
287 else
288 switch (*++pp)
289 {
290 case '(': case ')':
291 case 'I': case 'F': case 'N':
292 break;
91ce572a
CC
293 case 'V':
294 if (GET_MODE_CLASS (m1) == MODE_FLOAT)
295 printf ("v");
296 break;
af9e4a0c 297 case 'a':
a4ec8d12 298 for (np = GET_MODE_NAME(m1); *np; np++)
92a438d1 299 putchar (TOLOWER (*np));
af9e4a0c
RK
300 break;
301 case 'b':
a4ec8d12 302 for (np = GET_MODE_NAME(m2); *np; np++)
92a438d1 303 putchar (TOLOWER (*np));
af9e4a0c
RK
304 break;
305 case 'A':
1b3459d2 306 printf ("(int) %smode", GET_MODE_NAME(m1));
af9e4a0c
RK
307 break;
308 case 'B':
1b3459d2 309 printf ("(int) %smode", GET_MODE_NAME(m2));
af9e4a0c
RK
310 break;
311 case 'c':
5f06c983 312 printf ("%s", GET_RTX_NAME(op));
af9e4a0c
RK
313 break;
314 case 'C':
1b3459d2 315 printf ("(int) ");
5f06c983 316 for (np = GET_RTX_NAME(op); *np; np++)
92a438d1 317 putchar (TOUPPER (*np));
af9e4a0c
RK
318 break;
319 }
320 }
321
322 printf (";\n");
323}
af9e4a0c 324
3d7aafde 325extern int main (int, char **);
c1b59dce 326
af9e4a0c 327int
3d7aafde 328main (int argc, char **argv)
af9e4a0c
RK
329{
330 rtx desc;
af9e4a0c 331
f8b6598e 332 progname = "genopinit";
af9e4a0c
RK
333
334 if (argc <= 1)
1f978f5f 335 fatal ("no input file name");
af9e4a0c 336
04d8aa70 337 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 338 return (FATAL_EXIT_CODE);
af9e4a0c 339
af9e4a0c
RK
340 printf ("/* Generated automatically by the program `genopinit'\n\
341from the machine description file `md'. */\n\n");
342
343 printf ("#include \"config.h\"\n");
729da3f5 344 printf ("#include \"system.h\"\n");
4977bab6
ZW
345 printf ("#include \"coretypes.h\"\n");
346 printf ("#include \"tm.h\"\n");
af9e4a0c
RK
347 printf ("#include \"rtl.h\"\n");
348 printf ("#include \"flags.h\"\n");
af9e4a0c
RK
349 printf ("#include \"insn-config.h\"\n");
350 printf ("#include \"recog.h\"\n");
351 printf ("#include \"expr.h\"\n");
e78d8e51 352 printf ("#include \"optabs.h\"\n");
af9e4a0c
RK
353 printf ("#include \"reload.h\"\n\n");
354
6906ba40 355 printf ("void\ninit_all_optabs (void)\n{\n");
af9e4a0c
RK
356
357 /* Read the machine description. */
358
359 while (1)
360 {
c88c0d42
CP
361 int line_no, insn_code_number = 0;
362
363 desc = read_md_rtx (&line_no, &insn_code_number);
364 if (desc == NULL)
af9e4a0c 365 break;
af9e4a0c 366
af9e4a0c
RK
367 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
368 gen_insn (desc);
369 }
370
371 printf ("}\n");
372
373 fflush (stdout);
c1b59dce 374 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
af9e4a0c 375}
a995e389
RH
376
377/* Define this so we can link with print-rtl.o to get debug_rtx function. */
378const char *
3d7aafde 379get_insn_name (int code ATTRIBUTE_UNUSED)
a995e389
RH
380{
381 return NULL;
382}