]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / genopinit.c
CommitLineData
af9e4a0c 1/* Generate code to initialize optabs from machine description.
23a5b65a 2 Copyright (C) 1993-2014 Free Software Foundation, Inc.
af9e4a0c 3
1322177d 4This file is part of GCC.
af9e4a0c 5
1322177d
LB
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
af9e4a0c 10
1322177d
LB
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
af9e4a0c
RK
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
af9e4a0c
RK
19
20
4977bab6 21#include "bconfig.h"
0b93b64e 22#include "system.h"
4977bab6
ZW
23#include "coretypes.h"
24#include "tm.h"
af9e4a0c 25#include "rtl.h"
f8b6598e 26#include "errors.h"
c88c0d42 27#include "gensupport.h"
ccd043a9 28
af9e4a0c 29
cd1440b1 30#define DEF_RTL_EXPR(V, N, X, C) #V,
af9e4a0c 31
cd1440b1
RH
32static const char * const rtx_upname[] = {
33#include "rtl.def"
34};
35
36#undef DEF_RTL_EXPR
37
38
39/* The entries in optabs.def are categorized:
40 C: A "conversion" optab, which uses two modes; has libcall data.
41 N: A "normal" optab, which uses one mode; has libcall data.
42 D: A "direct" optab, which uses one mode; does not have libcall data.
43 V: An "oVerflow" optab. Like N, but does not record its code in
44 code_to_optab.
af9e4a0c 45
cd1440b1 46 CX, NX, VX: An extra pattern entry for a conversion or normal optab.
af9e4a0c 47
cd1440b1
RH
48 These patterns may be present in the MD file with names that contain
49 the mode(s) used and the name of the operation. This array contains
50 a list of optabs that need to be initialized. Within each name,
51 $a and $b are used to match a short mode name (the part of the mode
52 name not including `mode' and converted to lower-case).
a484f6ba
AS
53
54 $I means that only full integer modes should be considered for the
55 next mode, and $F means that only float modes should be considered.
91ce572a 56 $P means that both full and partial integer modes should be considered.
0f996086 57 $Q means that only fixed-point modes should be considered.
91ce572a 58
cd1440b1
RH
59 The pattern may be NULL if the optab exists only for the libcalls
60 that we plan to attach to it, and there are no named patterns in
61 the md files. */
62
63#define OPTAB_CL(name, pat, c, b, l) name,
64#define OPTAB_CX(name, pat)
65#define OPTAB_CD(name, pat) name,
66#define OPTAB_NL(name, pat, c, b, s, l) name,
67#define OPTAB_NC(name, pat, c) name,
68#define OPTAB_NX(name, pat)
69#define OPTAB_VL(name, pat, c, b, s, l) name,
70#define OPTAB_VC(name, pat, c) name,
71#define OPTAB_VX(name, pat)
72#define OPTAB_DC(name, pat, c) name,
73#define OPTAB_D(name, pat) name,
74
75typedef enum optab_tag {
76 unknown_optab,
77#include "optabs.def"
78 NUM_OPTABS
79} optab;
80
81#undef OPTAB_CL
82#undef OPTAB_CX
83#undef OPTAB_CD
84#undef OPTAB_NL
85#undef OPTAB_NC
86#undef OPTAB_NX
87#undef OPTAB_VL
88#undef OPTAB_VC
89#undef OPTAB_VX
90#undef OPTAB_DC
91#undef OPTAB_D
92
93#define NS "NULL"
94#define ZS "'\\0'"
95#define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
96#define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
97#define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
98#define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
99#define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
100#define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
101#define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
102#define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
103#define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
104#define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
105#define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
106
107typedef struct optab_def_d
108{
109 const char *name;
110 const char *pattern;
111 const char *base;
112 const char *suffix;
113 const char *libcall;
114 unsigned int op;
115 enum rtx_code fcode;
116 enum rtx_code rcode;
117 unsigned int kind;
118} optab_def;
119
120static optab_def optabs[] = {
121 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
122#include "optabs.def"
48ae6c13 123};
af9e4a0c 124
cd1440b1
RH
125#undef OPTAB_CL
126#undef OPTAB_CX
127#undef OPTAB_CD
128#undef OPTAB_NL
129#undef OPTAB_NC
130#undef OPTAB_NX
131#undef OPTAB_VL
132#undef OPTAB_VC
133#undef OPTAB_VX
134#undef OPTAB_DC
135#undef OPTAB_D
136
137/* Vector in which to collect insns that match. */
138
139typedef struct pattern_d
140{
141 const char *name;
142 unsigned int op;
143 unsigned int m1, m2;
144 unsigned int sort_num;
145} pattern;
146
cd1440b1 147
9771b263 148static vec<pattern> patterns;
cd1440b1
RH
149
150static bool
151match_pattern (pattern *p, const char *name, const char *pat)
152{
153 bool force_float = false;
154 bool force_int = false;
155 bool force_partial_int = false;
156 bool force_fixed = false;
157
158 if (pat == NULL)
159 return false;
160 for (; ; ++pat)
161 {
162 if (*pat != '$')
163 {
164 if (*pat != *name++)
165 return false;
166 if (*pat == '\0')
167 return true;
168 continue;
169 }
170 switch (*++pat)
171 {
172 case 'I':
173 force_int = 1;
174 break;
175 case 'P':
176 force_partial_int = 1;
177 break;
178 case 'F':
179 force_float = 1;
180 break;
181 case 'Q':
182 force_fixed = 1;
183 break;
184
185 case 'a':
186 case 'b':
187 {
188 int i;
189
190 /* This loop will stop at the first prefix match, so
191 look through the modes in reverse order, in case
192 there are extra CC modes and CC is a prefix of the
193 CC modes (as it should be). */
194 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
195 {
196 const char *p, *q;
c3284718 197 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
cd1440b1
RH
198 if (TOLOWER (*p) != *q)
199 break;
200 if (*p == 0
201 && (! force_int || mode_class[i] == MODE_INT
202 || mode_class[i] == MODE_VECTOR_INT)
203 && (! force_partial_int
204 || mode_class[i] == MODE_INT
205 || mode_class[i] == MODE_PARTIAL_INT
206 || mode_class[i] == MODE_VECTOR_INT)
207 && (! force_float
208 || mode_class[i] == MODE_FLOAT
209 || mode_class[i] == MODE_DECIMAL_FLOAT
210 || mode_class[i] == MODE_COMPLEX_FLOAT
211 || mode_class[i] == MODE_VECTOR_FLOAT)
212 && (! force_fixed
213 || mode_class[i] == MODE_FRACT
214 || mode_class[i] == MODE_UFRACT
215 || mode_class[i] == MODE_ACCUM
216 || mode_class[i] == MODE_UACCUM
217 || mode_class[i] == MODE_VECTOR_FRACT
218 || mode_class[i] == MODE_VECTOR_UFRACT
219 || mode_class[i] == MODE_VECTOR_ACCUM
220 || mode_class[i] == MODE_VECTOR_UACCUM))
221 break;
222 }
223
224 if (i < 0)
225 return false;
226 name += strlen (GET_MODE_NAME (i));
227 if (*pat == 'a')
228 p->m1 = i;
229 else
230 p->m2 = i;
231
232 force_int = false;
233 force_partial_int = false;
234 force_float = false;
235 force_fixed = false;
236 }
237 break;
238
239 default:
240 gcc_unreachable ();
241 }
242 }
243}
56c0e996 244
af9e4a0c 245static void
3d7aafde 246gen_insn (rtx insn)
af9e4a0c 247{
3cce094d 248 const char *name = XSTR (insn, 0);
cd1440b1
RH
249 pattern p;
250 unsigned pindex;
af9e4a0c 251
cd1440b1
RH
252 /* Don't mention "unnamed" instructions. */
253 if (*name == 0 || *name == '*')
254 return;
255 p.name = name;
af9e4a0c 256
cd1440b1
RH
257 /* See if NAME matches one of the patterns we have for the optabs
258 we know about. */
b6a1cbae 259 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
af9e4a0c 260 {
cd1440b1
RH
261 p.m1 = p.m2 = 0;
262 if (match_pattern (&p, name, optabs[pindex].pattern))
af9e4a0c 263 {
cd1440b1
RH
264 p.op = optabs[pindex].op;
265 p.sort_num = (p.op << 16) | (p.m2 << 8) | p.m1;
9771b263 266 patterns.safe_push (p);
cd1440b1 267 return;
af9e4a0c 268 }
af9e4a0c 269 }
cd1440b1 270}
af9e4a0c 271
cd1440b1
RH
272static int
273pattern_cmp (const void *va, const void *vb)
274{
275 const pattern *a = (const pattern *)va;
276 const pattern *b = (const pattern *)vb;
277 return a->sort_num - b->sort_num;
278}
af9e4a0c 279
cd1440b1
RH
280static int
281optab_kind_cmp (const void *va, const void *vb)
282{
283 const optab_def *a = (const optab_def *)va;
284 const optab_def *b = (const optab_def *)vb;
285 int diff = a->kind - b->kind;
286 if (diff == 0)
287 diff = a->op - b->op;
288 return diff;
289}
af9e4a0c 290
cd1440b1
RH
291static int
292optab_rcode_cmp (const void *va, const void *vb)
293{
294 const optab_def *a = (const optab_def *)va;
295 const optab_def *b = (const optab_def *)vb;
296 return a->rcode - b->rcode;
297}
af9e4a0c 298
cd1440b1
RH
299static const char *header_file_name = "init-opinit.h";
300static const char *source_file_name = "init-opinit.c";
af9e4a0c 301
cd1440b1
RH
302static bool
303handle_arg (const char *arg)
304{
305 switch (arg[1])
af9e4a0c 306 {
cd1440b1
RH
307 case 'h':
308 header_file_name = &arg[2];
309 return true;
310 case 'c':
311 source_file_name = &arg[2];
312 return true;
313 default:
314 return false;
af9e4a0c 315 }
af9e4a0c 316}
af9e4a0c 317
cd1440b1
RH
318static FILE *
319open_outfile (const char *file_name)
320{
321 FILE *f = fopen (file_name, "w");
322 if (!f)
323 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
324 fprintf (f,
325 "/* Generated automatically by the program `genopinit'\n"
326 " from the machine description file `md'. */\n\n");
327 return f;
328}
c1b59dce 329
af9e4a0c 330int
3d7aafde 331main (int argc, char **argv)
af9e4a0c 332{
cd1440b1
RH
333 FILE *h_file, *s_file;
334 unsigned int i, j, n, last_kind[5];
335 pattern *p;
af9e4a0c 336
f8b6598e 337 progname = "genopinit";
af9e4a0c 338
cd1440b1
RH
339 if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
340 fatal ("genopinit range assumptions invalid");
341
342 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
c88c0d42 343 return (FATAL_EXIT_CODE);
af9e4a0c 344
cd1440b1
RH
345 h_file = open_outfile (header_file_name);
346 s_file = open_outfile (source_file_name);
dcc3fcf2 347
af9e4a0c 348 /* Read the machine description. */
af9e4a0c
RK
349 while (1)
350 {
c88c0d42 351 int line_no, insn_code_number = 0;
cd1440b1 352 rtx desc = read_md_rtx (&line_no, &insn_code_number);
c88c0d42 353 if (desc == NULL)
af9e4a0c 354 break;
af9e4a0c
RK
355 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
356 gen_insn (desc);
357 }
358
cd1440b1 359 /* Sort the collected patterns. */
9771b263 360 qsort (patterns.address (), patterns.length (),
cd1440b1
RH
361 sizeof (pattern), pattern_cmp);
362
363 /* Now that we've handled the "extra" patterns, eliminate them from
364 the optabs array. That way they don't get in the way below. */
365 n = ARRAY_SIZE (optabs);
366 for (i = 0; i < n; )
367 if (optabs[i].base == NULL)
368 optabs[i] = optabs[--n];
369 else
370 ++i;
371
372 /* Sort the (real) optabs. Better than forcing the optabs.def file to
373 remain sorted by kind. We also scrogged any real ordering with the
374 purging of the X patterns above. */
c3284718 375 qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
cd1440b1
RH
376
377 /* Emit the optab enumeration for the header file. */
378 fprintf (h_file, "enum optab_tag {\n");
379 for (i = j = 0; i < n; ++i)
380 {
381 optabs[i].op = i;
382 fprintf (h_file, " %s,\n", optabs[i].name);
383 if (optabs[i].kind != j)
384 last_kind[j++] = i - 1;
385 }
386 fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
387 fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
388 fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
389 fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
390 fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
391 fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
392 fprintf (h_file, "};\n\n");
393
394 fprintf (h_file, "#define NUM_OPTABS %u\n", n);
395 fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
396 last_kind[1] - last_kind[0]);
397 fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
398 last_kind[3] - last_kind[2]);
399 fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
9771b263 400 (unsigned) patterns.length ());
cd1440b1
RH
401
402 fprintf (s_file,
403 "#include \"config.h\"\n"
404 "#include \"system.h\"\n"
405 "#include \"coretypes.h\"\n"
406 "#include \"tm.h\"\n"
4d648807 407 "#include \"tree.h\"\n"
d8a2d370
DN
408 "#include \"varasm.h\"\n"
409 "#include \"stor-layout.h\"\n"
410 "#include \"calls.h\"\n"
cd1440b1
RH
411 "#include \"rtl.h\"\n"
412 "#include \"tm_p.h\"\n"
413 "#include \"flags.h\"\n"
414 "#include \"insn-config.h\"\n"
415 "#include \"expr.h\"\n"
416 "#include \"optabs.h\"\n"
417 "\n"
418 "struct optab_pat {\n"
419 " unsigned scode;\n"
420 " enum insn_code icode;\n"
421 "};\n\n");
422
423 fprintf (s_file,
424 "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
9771b263 425 for (i = 0; patterns.iterate (i, &p); ++i)
cd1440b1
RH
426 fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
427 fprintf (s_file, "};\n\n");
428
135204dd
AH
429 fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
430 fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
9771b263 431 for (i = 0; patterns.iterate (i, &p); ++i)
cd1440b1
RH
432 fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
433 fprintf (s_file, "}\n\n");
434
435 /* Perform a binary search on a pre-encoded optab+mode*2. */
436 /* ??? Perhaps even better to generate a minimal perfect hash.
437 Using gperf directly is awkward since it's so geared to working
438 with strings. Plus we have no visibility into the ordering of
439 the hash entries, which complicates the pat_enable array. */
440 fprintf (s_file,
441 "static int\n"
442 "lookup_handler (unsigned scode)\n"
443 "{\n"
444 " int l = 0, h = ARRAY_SIZE (pats), m;\n"
445 " while (h > l)\n"
446 " {\n"
447 " m = (h + l) / 2;\n"
448 " if (scode == pats[m].scode)\n"
449 " return m;\n"
450 " else if (scode < pats[m].scode)\n"
451 " h = m;\n"
452 " else\n"
453 " l = m + 1;\n"
454 " }\n"
455 " return -1;\n"
456 "}\n\n");
457
458 fprintf (s_file,
459 "enum insn_code\n"
460 "raw_optab_handler (unsigned scode)\n"
461 "{\n"
462 " int i = lookup_handler (scode);\n"
135204dd 463 " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
cd1440b1
RH
464 " ? pats[i].icode : CODE_FOR_nothing);\n"
465 "}\n\n");
466
467 fprintf (s_file,
468 "bool\n"
469 "swap_optab_enable (optab op, enum machine_mode m, bool set)\n"
470 "{\n"
471 " unsigned scode = (op << 16) | m;\n"
472 " int i = lookup_handler (scode);\n"
473 " if (i >= 0)\n"
474 " {\n"
135204dd
AH
475 " bool ret = this_fn_optabs->pat_enable[i];\n"
476 " this_fn_optabs->pat_enable[i] = set;\n"
cd1440b1
RH
477 " return ret;\n"
478 " }\n"
479 " else\n"
480 " {\n"
481 " gcc_assert (!set);\n"
482 " return false;\n"
483 " }\n"
484 "}\n\n");
485
486 /* C++ (even G++) does not support (non-trivial) designated initializers.
487 To work around that, generate these arrays programatically rather than
488 by our traditional multiple inclusion of def files. */
489
490 fprintf (s_file,
491 "const struct convert_optab_libcall_d "
492 "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
493 for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
494 fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
495 fprintf (s_file, "};\n\n");
496
497 fprintf (s_file,
498 "const struct optab_libcall_d "
499 "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
500 for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
501 fprintf (s_file, " { %s, %s, %s },\n",
502 optabs[i].suffix, optabs[i].base, optabs[i].libcall);
503 fprintf (s_file, "};\n\n");
504
505 fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
506 for (i = 0; i < n; ++i)
507 fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
508 fprintf (s_file, "};\n\n");
509
510 qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
511
512 fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
513 for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
514 continue;
515 for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
516 {
517 if (j < n && optabs[j].rcode == i)
518 fprintf (s_file, " %s,\n", optabs[j++].name);
519 else
520 fprintf (s_file, " unknown_optab,\n");
521 }
522 fprintf (s_file, "};\n\n");
523
524 return (fclose (h_file) == 0 && fclose (s_file) == 0
525 ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
af9e4a0c 526}