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