revert:
[official-gcc.git] / gcc / genopinit.c
blob167815d561d50247226f6e014f937617d7304e86
1 /* Generate code to initialize optabs from machine description.
2 Copyright (C) 1993-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include "bconfig.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "errors.h"
27 #include "gensupport.h"
30 #define DEF_RTL_EXPR(V, N, X, C) #V,
32 static const char * const rtx_upname[] = {
33 #include "rtl.def"
36 #undef DEF_RTL_EXPR
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.
46 CX, NX, VX: An extra pattern entry for a conversion or normal optab.
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).
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.
56 $P means that both full and partial integer modes should be considered.
57 $Q means that only fixed-point modes should be considered.
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. */
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,
75 typedef enum optab_tag {
76 unknown_optab,
77 #include "optabs.def"
78 NUM_OPTABS
79 } optab;
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
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 },
107 struct optab_def
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;
120 static optab_def optabs[] = {
121 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
122 #include "optabs.def"
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
137 /* Vector in which to collect insns that match. */
139 struct pattern
141 const char *name;
142 unsigned int op;
143 unsigned int m1, m2;
144 unsigned int sort_num;
148 static vec<pattern> patterns;
150 static bool
151 match_pattern (pattern *p, const char *name, const char *pat)
153 bool force_float = false;
154 bool force_int = false;
155 bool force_partial_int = false;
156 bool force_fixed = false;
158 if (pat == NULL)
159 return false;
160 for (; ; ++pat)
162 if (*pat != '$')
164 if (*pat != *name++)
165 return false;
166 if (*pat == '\0')
167 return true;
168 continue;
170 switch (*++pat)
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;
185 case 'a':
186 case 'b':
188 int i;
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--)
196 const char *p, *q;
197 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
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;
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;
232 force_int = false;
233 force_partial_int = false;
234 force_float = false;
235 force_fixed = false;
237 break;
239 default:
240 gcc_unreachable ();
245 static void
246 gen_insn (md_rtx_info *info)
248 rtx insn = info->def;
249 const char *name = XSTR (insn, 0);
250 pattern p;
251 unsigned pindex;
253 /* Don't mention "unnamed" instructions. */
254 if (*name == 0 || *name == '*')
255 return;
256 p.name = name;
258 /* See if NAME matches one of the patterns we have for the optabs
259 we know about. */
260 for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
262 p.m1 = p.m2 = 0;
263 if (match_pattern (&p, name, optabs[pindex].pattern))
265 p.op = optabs[pindex].op;
266 p.sort_num = (p.op << 16) | (p.m2 << 8) | p.m1;
267 patterns.safe_push (p);
268 return;
273 static int
274 pattern_cmp (const void *va, const void *vb)
276 const pattern *a = (const pattern *)va;
277 const pattern *b = (const pattern *)vb;
278 return a->sort_num - b->sort_num;
281 static int
282 optab_kind_cmp (const void *va, const void *vb)
284 const optab_def *a = (const optab_def *)va;
285 const optab_def *b = (const optab_def *)vb;
286 int diff = a->kind - b->kind;
287 if (diff == 0)
288 diff = a->op - b->op;
289 return diff;
292 static int
293 optab_rcode_cmp (const void *va, const void *vb)
295 const optab_def *a = (const optab_def *)va;
296 const optab_def *b = (const optab_def *)vb;
297 return a->rcode - b->rcode;
300 static const char *header_file_name = "init-opinit.h";
301 static const char *source_file_name = "init-opinit.c";
303 static bool
304 handle_arg (const char *arg)
306 switch (arg[1])
308 case 'h':
309 header_file_name = &arg[2];
310 return true;
311 case 'c':
312 source_file_name = &arg[2];
313 return true;
314 default:
315 return false;
319 static FILE *
320 open_outfile (const char *file_name)
322 FILE *f = fopen (file_name, "w");
323 if (!f)
324 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
325 fprintf (f,
326 "/* Generated automatically by the program `genopinit'\n"
327 " from the machine description file `md'. */\n\n");
328 return f;
332 main (int argc, char **argv)
334 FILE *h_file, *s_file;
335 unsigned int i, j, n, last_kind[5];
336 pattern *p;
338 progname = "genopinit";
340 if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
341 fatal ("genopinit range assumptions invalid");
343 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
344 return (FATAL_EXIT_CODE);
346 h_file = open_outfile (header_file_name);
347 s_file = open_outfile (source_file_name);
349 /* Read the machine description. */
350 md_rtx_info info;
351 while (read_md_rtx (&info))
352 switch (GET_CODE (info.def))
354 case DEFINE_INSN:
355 case DEFINE_EXPAND:
356 gen_insn (&info);
357 break;
359 default:
360 break;
363 /* Sort the collected patterns. */
364 patterns.qsort (pattern_cmp);
366 /* Now that we've handled the "extra" patterns, eliminate them from
367 the optabs array. That way they don't get in the way below. */
368 n = ARRAY_SIZE (optabs);
369 for (i = 0; i < n; )
370 if (optabs[i].base == NULL)
371 optabs[i] = optabs[--n];
372 else
373 ++i;
375 /* Sort the (real) optabs. Better than forcing the optabs.def file to
376 remain sorted by kind. We also scrogged any real ordering with the
377 purging of the X patterns above. */
378 qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
380 fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
381 fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");
383 /* Emit the optab enumeration for the header file. */
384 fprintf (h_file, "enum optab_tag {\n");
385 for (i = j = 0; i < n; ++i)
387 optabs[i].op = i;
388 fprintf (h_file, " %s,\n", optabs[i].name);
389 if (optabs[i].kind != j)
390 last_kind[j++] = i - 1;
392 fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
393 fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
394 fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
395 fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
396 fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
397 fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
398 fprintf (h_file, "};\n\n");
400 fprintf (h_file, "#define NUM_OPTABS %u\n", n);
401 fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
402 last_kind[1] - last_kind[0]);
403 fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
404 last_kind[3] - last_kind[2]);
405 fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
406 (unsigned) patterns.length ());
408 fprintf (h_file,
409 "typedef enum optab_tag optab;\n"
410 "typedef enum optab_tag convert_optab;\n"
411 "typedef enum optab_tag direct_optab;\n"
412 "\n"
413 "struct optab_libcall_d\n"
414 "{\n"
415 " char libcall_suffix;\n"
416 " const char *libcall_basename;\n"
417 " void (*libcall_gen) (optab, const char *name,\n"
418 " char suffix, machine_mode);\n"
419 "};\n"
420 "\n"
421 "struct convert_optab_libcall_d\n"
422 "{\n"
423 " const char *libcall_basename;\n"
424 " void (*libcall_gen) (convert_optab, const char *name,\n"
425 " machine_mode, machine_mode);\n"
426 "};\n"
427 "\n"
428 "/* Given an enum insn_code, access the function to construct\n"
429 " the body of that kind of insn. */\n"
430 "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
431 "\n"
432 "#ifdef NUM_RTX_CODE\n"
433 "/* Contains the optab used for each rtx code, and vice-versa. */\n"
434 "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
435 "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
436 "\n"
437 "static inline optab\n"
438 "code_to_optab (enum rtx_code code)\n"
439 "{\n"
440 " return code_to_optab_[code];\n"
441 "}\n"
442 "\n"
443 "static inline enum rtx_code\n"
444 "optab_to_code (optab op)\n"
445 "{\n"
446 " return optab_to_code_[op];\n"
447 "}\n"
448 "#endif\n"
449 "\n"
450 "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
451 "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
452 "\n"
453 "/* Returns the active icode for the given (encoded) optab. */\n"
454 "extern enum insn_code raw_optab_handler (unsigned);\n"
455 "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
456 "\n"
457 "/* Target-dependent globals. */\n"
458 "struct target_optabs {\n"
459 " /* Patterns that are used by optabs that are enabled for this target. */\n"
460 " bool pat_enable[NUM_OPTAB_PATTERNS];\n"
461 "};\n"
462 "extern void init_all_optabs (struct target_optabs *);\n"
463 "\n"
464 "extern struct target_optabs default_target_optabs;\n"
465 "extern struct target_optabs *this_fn_optabs;\n"
466 "#if SWITCHABLE_TARGET\n"
467 "extern struct target_optabs *this_target_optabs;\n"
468 "#else\n"
469 "#define this_target_optabs (&default_target_optabs)\n"
470 "#endif\n");
472 fprintf (s_file,
473 "#include \"config.h\"\n"
474 "#include \"system.h\"\n"
475 "#include \"coretypes.h\"\n"
476 "#include \"backend.h\"\n"
477 "#include \"predict.h\"\n"
478 "#include \"tree.h\"\n"
479 "#include \"rtl.h\"\n"
480 "#include \"alias.h\"\n"
481 "#include \"varasm.h\"\n"
482 "#include \"stor-layout.h\"\n"
483 "#include \"calls.h\"\n"
484 "#include \"tm_p.h\"\n"
485 "#include \"flags.h\"\n"
486 "#include \"insn-config.h\"\n"
487 "#include \"expmed.h\"\n"
488 "#include \"dojump.h\"\n"
489 "#include \"explow.h\"\n"
490 "#include \"emit-rtl.h\"\n"
491 "#include \"stmt.h\"\n"
492 "#include \"expr.h\"\n"
493 "#include \"insn-codes.h\"\n"
494 "#include \"optabs.h\"\n"
495 "\n"
496 "struct optab_pat {\n"
497 " unsigned scode;\n"
498 " enum insn_code icode;\n"
499 "};\n\n");
501 fprintf (s_file,
502 "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
503 for (i = 0; patterns.iterate (i, &p); ++i)
504 fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
505 fprintf (s_file, "};\n\n");
507 fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
508 fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
509 for (i = 0; patterns.iterate (i, &p); ++i)
510 fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
511 fprintf (s_file, "}\n\n");
513 /* Perform a binary search on a pre-encoded optab+mode*2. */
514 /* ??? Perhaps even better to generate a minimal perfect hash.
515 Using gperf directly is awkward since it's so geared to working
516 with strings. Plus we have no visibility into the ordering of
517 the hash entries, which complicates the pat_enable array. */
518 fprintf (s_file,
519 "static int\n"
520 "lookup_handler (unsigned scode)\n"
521 "{\n"
522 " int l = 0, h = ARRAY_SIZE (pats), m;\n"
523 " while (h > l)\n"
524 " {\n"
525 " m = (h + l) / 2;\n"
526 " if (scode == pats[m].scode)\n"
527 " return m;\n"
528 " else if (scode < pats[m].scode)\n"
529 " h = m;\n"
530 " else\n"
531 " l = m + 1;\n"
532 " }\n"
533 " return -1;\n"
534 "}\n\n");
536 fprintf (s_file,
537 "enum insn_code\n"
538 "raw_optab_handler (unsigned scode)\n"
539 "{\n"
540 " int i = lookup_handler (scode);\n"
541 " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
542 " ? pats[i].icode : CODE_FOR_nothing);\n"
543 "}\n\n");
545 fprintf (s_file,
546 "bool\n"
547 "swap_optab_enable (optab op, machine_mode m, bool set)\n"
548 "{\n"
549 " unsigned scode = (op << 16) | m;\n"
550 " int i = lookup_handler (scode);\n"
551 " if (i >= 0)\n"
552 " {\n"
553 " bool ret = this_fn_optabs->pat_enable[i];\n"
554 " this_fn_optabs->pat_enable[i] = set;\n"
555 " return ret;\n"
556 " }\n"
557 " else\n"
558 " {\n"
559 " gcc_assert (!set);\n"
560 " return false;\n"
561 " }\n"
562 "}\n\n");
564 /* C++ (even G++) does not support (non-trivial) designated initializers.
565 To work around that, generate these arrays programatically rather than
566 by our traditional multiple inclusion of def files. */
568 fprintf (s_file,
569 "const struct convert_optab_libcall_d "
570 "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
571 for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
572 fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
573 fprintf (s_file, "};\n\n");
575 fprintf (s_file,
576 "const struct optab_libcall_d "
577 "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
578 for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
579 fprintf (s_file, " { %s, %s, %s },\n",
580 optabs[i].suffix, optabs[i].base, optabs[i].libcall);
581 fprintf (s_file, "};\n\n");
583 fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
584 for (i = 0; i < n; ++i)
585 fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
586 fprintf (s_file, "};\n\n");
588 qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
590 fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
591 for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
592 continue;
593 for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
595 if (j < n && optabs[j].rcode == i)
596 fprintf (s_file, " %s,\n", optabs[j++].name);
597 else
598 fprintf (s_file, " unknown_optab,\n");
600 fprintf (s_file, "};\n\n");
602 fprintf (h_file, "#endif\n");
603 return (fclose (h_file) == 0 && fclose (s_file) == 0
604 ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);