]> gcc.gnu.org Git - gcc.git/blame - gcc/genopinit.c
* gcc.c-torture/compile/20000518-1.c: New test.
[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
RK
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
a35311b0
RK
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-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
41 with %( and %). In the string, %a and %b are used to match a short mode
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
44 used. %A and %B are replaced with the full name of the mode; %a and %b
45 are replaced with the short form of the name, as above.
46
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
49 only integer modes should be considered for the next mode, and %F means
50 that only float modes should be considered.
51
52 For some optabs, we store the operation by RTL codes. These are only
53 used for comparisons. In that case, %c and %C are the lower-case and
54 upper-case forms of the comparison, respectively. */
55
8c9881d1
RS
56/* The reason we use \% is to avoid sequences of the form %-capletter-%
57 which SCCS treats as magic. This gets warnings which you should ignore. */
58
c1b59dce 59const char * const optabs[] =
8c9881d1
RS
60{ "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
61 "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
62 "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
63 "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)",
64 "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)",
65 "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)",
66 "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)",
53f26922 67 "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)",
af9e4a0c
RK
68 "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)",
69 "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)",
70 "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)",
af309004
TG
71 "umul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umul%a3_highpart%)",
72 "smul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smul%a3_highpart%)",
af9e4a0c
RK
73 "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N",
74 "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N",
8c9881d1
RS
75 "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)",
76 "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)",
af9e4a0c
RK
77 "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)",
78 "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)",
79 "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)",
80 "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)",
8c9881d1
RS
81 "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)",
82 "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)",
af9e4a0c
RK
83 "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)",
84 "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)",
85 "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)",
86 "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)",
87 "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)",
af9e4a0c
RK
88 "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)",
89 "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)",
90 "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)",
8c9881d1
RS
91 "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)",
92 "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)",
93 "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)",
94 "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)",
95 "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)",
96 "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)",
af9e4a0c
RK
97 "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)",
98 "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)",
99 "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)",
100 "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)",
101 "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)",
ed58a128 102 "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)",
af9e4a0c
RK
103 "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)",
104 "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)",
105 "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)",
106 "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)",
107 "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)",
108 "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)",
109 "bcc_gen_fctn[(int) %C] = gen_%(b%c%)",
110 "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)",
3c9958cd 111 "movcc_gen_code[(int) %A] = CODE_FOR_%(mov%acc%)",
1c0290ea
BS
112 "cbranch_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cbranch%a4%)",
113 "cmov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmov%a6%)",
114 "cstore_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cstore%a4%)",
af9e4a0c
RK
115 "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)",
116 "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)",
fd18db65
RK
117 "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)",
118 "clrstr_optab[(int) %A] = CODE_FOR_%(clrstr%a%)" };
af9e4a0c 119
a94ae8f5 120static void gen_insn PARAMS ((rtx));
56c0e996 121
af9e4a0c
RK
122static void
123gen_insn (insn)
124 rtx insn;
125{
3cce094d 126 const char *name = XSTR (insn, 0);
a544cfd2 127 int m1 = 0, m2 = 0, op = 0;
5ae9a7e9 128 size_t pindex;
af9e4a0c 129 int i;
85fda1eb 130 const char *np, *pp, *p, *q;
af9e4a0c
RK
131
132 /* Don't mention instructions whose names are the null string.
133 They are in the machine description just to be recognized. */
134 if (*name == 0)
135 return;
136
137 /* See if NAME matches one of the patterns we have for the optabs we know
138 about. */
139
140 for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++)
141 {
142 int force_float = 0, force_int = 0;
143 int force_consec = 0;
144 int matches = 1;
145
146 for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++)
147 ;
148
149 for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')');
150 pp++)
151 {
152 if (*pp != '%')
153 {
154 if (*pp != *np++)
155 break;
156 }
157 else
158 switch (*++pp)
159 {
160 case 'N':
161 force_consec = 1;
162 break;
163 case 'I':
164 force_int = 1;
165 break;
166 case 'F':
167 force_float = 1;
168 break;
169 case 'c':
170 for (op = 0; op < NUM_RTX_CODE; op++)
171 {
5f06c983 172 for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
af9e4a0c
RK
173 if (*p != *q)
174 break;
175
176 /* We have to be concerned about matching "gt" and
177 missing "gtu", e.g., so verify we have reached the
4639555c 178 end of thing we are to match. */
1f9a015e 179 if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
af9e4a0c
RK
180 break;
181 }
182
183 if (op == NUM_RTX_CODE)
184 matches = 0;
185 else
5f06c983 186 np += strlen (GET_RTX_NAME(op));
af9e4a0c
RK
187 break;
188 case 'a':
189 case 'b':
4639555c
ILT
190 /* This loop will stop at the first prefix match, so
191 look through the modes in reverse order, in case
192 EXTRA_CC_MODES was used and CC is a prefix of the
193 CC modes (as it should be). */
194 for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
af9e4a0c 195 {
a4ec8d12 196 for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
92a438d1 197 if (TOLOWER (*p) != *q)
af9e4a0c
RK
198 break;
199
200 if (*p == 0
201 && (! force_int || mode_class[i] == MODE_INT)
202 && (! force_float || mode_class[i] == MODE_FLOAT))
203 break;
204 }
205
4639555c 206 if (i < 0)
af9e4a0c
RK
207 matches = 0;
208 else if (*pp == 'a')
a4ec8d12 209 m1 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c 210 else
a4ec8d12 211 m2 = i, np += strlen (GET_MODE_NAME(i));
af9e4a0c
RK
212
213 force_int = force_float = 0;
214 break;
215
216 default:
217 abort ();
218 }
219 }
220
221 if (matches && pp[0] == '%' && pp[1] == ')'
222 && *np == 0
88a5e9da 223 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
af9e4a0c
RK
224 break;
225 }
226
227 if (pindex == sizeof optabs / sizeof optabs[0])
228 return;
229
230 /* We found a match. If this pattern is only conditionally present,
231 write out the "if" and two extra blanks. */
232
233 if (*XSTR (insn, 2) != 0)
234 printf (" if (HAVE_%s)\n ", name);
235
236 printf (" ");
237
238 /* Now write out the initialization, making all required substitutions. */
239 for (pp = optabs[pindex]; *pp; pp++)
240 {
241 if (*pp != '%')
242 printf ("%c", *pp);
243 else
244 switch (*++pp)
245 {
246 case '(': case ')':
247 case 'I': case 'F': case 'N':
248 break;
249 case 'a':
a4ec8d12 250 for (np = GET_MODE_NAME(m1); *np; np++)
92a438d1 251 putchar (TOLOWER (*np));
af9e4a0c
RK
252 break;
253 case 'b':
a4ec8d12 254 for (np = GET_MODE_NAME(m2); *np; np++)
92a438d1 255 putchar (TOLOWER (*np));
af9e4a0c
RK
256 break;
257 case 'A':
a4ec8d12 258 printf ("%smode", GET_MODE_NAME(m1));
af9e4a0c
RK
259 break;
260 case 'B':
a4ec8d12 261 printf ("%smode", GET_MODE_NAME(m2));
af9e4a0c
RK
262 break;
263 case 'c':
5f06c983 264 printf ("%s", GET_RTX_NAME(op));
af9e4a0c
RK
265 break;
266 case 'C':
5f06c983 267 for (np = GET_RTX_NAME(op); *np; np++)
92a438d1 268 putchar (TOUPPER (*np));
af9e4a0c
RK
269 break;
270 }
271 }
272
273 printf (";\n");
274}
275\f
2778b98d 276PTR
af9e4a0c 277xmalloc (size)
2778b98d 278 size_t size;
af9e4a0c 279{
2778b98d 280 register PTR val = (PTR) malloc (size);
af9e4a0c
RK
281
282 if (val == 0)
283 fatal ("virtual memory exhausted");
284
285 return val;
286}
287
2778b98d 288PTR
470b68c0
RH
289xrealloc (old, size)
290 PTR old;
2778b98d 291 size_t size;
af9e4a0c 292{
470b68c0 293 register PTR ptr;
09d83d25 294 if (old)
470b68c0
RH
295 ptr = (PTR) realloc (old, size);
296 else
297 ptr = (PTR) malloc (size);
298 if (!ptr)
af9e4a0c 299 fatal ("virtual memory exhausted");
470b68c0 300 return ptr;
af9e4a0c
RK
301}
302
a94ae8f5 303extern int main PARAMS ((int, char **));
c1b59dce 304
af9e4a0c
RK
305int
306main (argc, argv)
307 int argc;
308 char **argv;
309{
310 rtx desc;
af9e4a0c 311
f8b6598e 312 progname = "genopinit";
af9e4a0c
RK
313
314 if (argc <= 1)
315 fatal ("No input file name.");
316
c88c0d42
CP
317 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
318 return (FATAL_EXIT_CODE);
af9e4a0c 319
af9e4a0c
RK
320 printf ("/* Generated automatically by the program `genopinit'\n\
321from the machine description file `md'. */\n\n");
322
323 printf ("#include \"config.h\"\n");
729da3f5 324 printf ("#include \"system.h\"\n");
af9e4a0c
RK
325 printf ("#include \"rtl.h\"\n");
326 printf ("#include \"flags.h\"\n");
327 printf ("#include \"insn-flags.h\"\n");
328 printf ("#include \"insn-codes.h\"\n");
329 printf ("#include \"insn-config.h\"\n");
330 printf ("#include \"recog.h\"\n");
331 printf ("#include \"expr.h\"\n");
332 printf ("#include \"reload.h\"\n\n");
333
334 printf ("void\ninit_all_optabs ()\n{\n");
335
336 /* Read the machine description. */
337
338 while (1)
339 {
c88c0d42
CP
340 int line_no, insn_code_number = 0;
341
342 desc = read_md_rtx (&line_no, &insn_code_number);
343 if (desc == NULL)
af9e4a0c 344 break;
af9e4a0c 345
af9e4a0c
RK
346 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
347 gen_insn (desc);
348 }
349
350 printf ("}\n");
351
352 fflush (stdout);
c1b59dce 353 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
af9e4a0c 354}
a995e389
RH
355
356/* Define this so we can link with print-rtl.o to get debug_rtx function. */
357const char *
358get_insn_name (code)
c1b59dce 359 int code ATTRIBUTE_UNUSED;
a995e389
RH
360{
361 return NULL;
362}
This page took 0.837932 seconds and 5 git commands to generate.