gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / gcc / genopinit.c
1 /* Generate code to initialize optabs from machine description.
2    Copyright (C) 1993-2015 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>.  */
19
20
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"
28
29
30 #define DEF_RTL_EXPR(V, N, X, C) #V,
31
32 static 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.
45
46      CX, NX, VX: An extra pattern entry for a conversion or normal optab.
47
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).
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.
56    $P means that both full and partial integer modes should be considered.
57    $Q means that only fixed-point modes should be considered.
58
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
75 typedef 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
107 typedef 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
120 static optab_def optabs[] = {
121   { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
122 #include "optabs.def"
123 };
124
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
139 typedef 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
147
148 static vec<pattern> patterns;
149
150 static bool
151 match_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;
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;
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 }
244
245 static void
246 gen_insn (rtx insn)
247 {
248   const char *name = XSTR (insn, 0);
249   pattern p;
250   unsigned pindex;
251
252   /* Don't mention "unnamed" instructions.  */
253   if (*name == 0 || *name == '*')
254     return;
255   p.name = name;
256
257   /* See if NAME matches one of the patterns we have for the optabs
258      we know about.  */
259   for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
260     {
261       p.m1 = p.m2 = 0;
262       if (match_pattern (&p, name, optabs[pindex].pattern))
263         {
264           p.op = optabs[pindex].op;
265           p.sort_num = (p.op << 16) | (p.m2 << 8) | p.m1;
266           patterns.safe_push (p);
267           return;
268         }
269     }
270 }
271
272 static int
273 pattern_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 }
279
280 static int
281 optab_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 }
290
291 static int
292 optab_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 }
298
299 static const char *header_file_name = "init-opinit.h";
300 static const char *source_file_name = "init-opinit.c";
301
302 static bool
303 handle_arg (const char *arg)
304 {
305   switch (arg[1])
306     {
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;
315     }
316 }
317
318 static FILE *
319 open_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 }
329
330 int
331 main (int argc, char **argv)
332 {
333   FILE *h_file, *s_file;
334   unsigned int i, j, n, last_kind[5];
335   pattern *p;
336
337   progname = "genopinit";
338
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))
343     return (FATAL_EXIT_CODE);
344
345   h_file = open_outfile (header_file_name);
346   s_file = open_outfile (source_file_name);
347
348   /* Read the machine description.  */
349   while (1)
350     {
351       int line_no, insn_code_number = 0;
352       rtx desc = read_md_rtx (&line_no, &insn_code_number);
353       if (desc == NULL)
354         break;
355       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
356         gen_insn (desc);
357     }
358
359   /* Sort the collected patterns.  */
360   patterns.qsort (pattern_cmp);
361
362   /* Now that we've handled the "extra" patterns, eliminate them from
363      the optabs array.  That way they don't get in the way below.  */
364   n = ARRAY_SIZE (optabs);
365   for (i = 0; i < n; )
366     if (optabs[i].base == NULL)
367       optabs[i] = optabs[--n];
368     else
369       ++i;
370
371   /* Sort the (real) optabs.  Better than forcing the optabs.def file to
372      remain sorted by kind.  We also scrogged any real ordering with the
373      purging of the X patterns above.  */
374   qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
375
376   /* Emit the optab enumeration for the header file.  */
377   fprintf (h_file, "enum optab_tag {\n");
378   for (i = j = 0; i < n; ++i)
379     {
380       optabs[i].op = i;
381       fprintf (h_file, "  %s,\n", optabs[i].name);
382       if (optabs[i].kind != j)
383         last_kind[j++] = i - 1;
384     }
385   fprintf (h_file, "  FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
386   fprintf (h_file, "  LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
387   fprintf (h_file, "  LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
388   fprintf (h_file, "  FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
389   fprintf (h_file, "  LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
390   fprintf (h_file, "  LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
391   fprintf (h_file, "};\n\n");
392
393   fprintf (h_file, "#define NUM_OPTABS          %u\n", n);
394   fprintf (h_file, "#define NUM_CONVLIB_OPTABS  %u\n",
395            last_kind[1] - last_kind[0]);
396   fprintf (h_file, "#define NUM_NORMLIB_OPTABS  %u\n",
397            last_kind[3] - last_kind[2]);
398   fprintf (h_file, "#define NUM_OPTAB_PATTERNS  %u\n",
399            (unsigned) patterns.length ());
400
401   fprintf (h_file, 
402            "typedef enum optab_tag optab;\n"
403            "typedef enum optab_tag convert_optab;\n"
404            "typedef enum optab_tag direct_optab;\n"
405            "\n"
406            "struct optab_libcall_d\n"
407            "{\n"
408            "  char libcall_suffix;\n"
409            "  const char *libcall_basename;\n"
410            "  void (*libcall_gen) (optab, const char *name,\n"
411            "                   char suffix, machine_mode);\n"
412            "};\n"
413            "\n"
414            "struct convert_optab_libcall_d\n"
415            "{\n"
416            "  const char *libcall_basename;\n"
417            "  void (*libcall_gen) (convert_optab, const char *name,\n"
418            "                   machine_mode, machine_mode);\n"
419            "};\n"
420            "\n"
421            "/* Given an enum insn_code, access the function to construct\n"
422            "   the body of that kind of insn.  */\n"
423            "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
424            "\n"
425            "/* Contains the optab used for each rtx code, and vice-versa.  */\n"
426            "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
427            "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
428            "\n"
429            "static inline optab\n"
430            "code_to_optab (enum rtx_code code)\n"
431            "{\n"
432            "  return code_to_optab_[code];\n"
433            "}\n"
434            "\n"
435            "static inline enum rtx_code\n"
436            "optab_to_code (optab op)\n"
437            "{\n"
438            "  return optab_to_code_[op];\n"
439            "}\n"
440            "\n"
441            "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
442            "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
443            "\n"
444            "/* Returns the active icode for the given (encoded) optab.  */\n"
445            "extern enum insn_code raw_optab_handler (unsigned);\n"
446            "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
447            "\n"
448            "/* Target-dependent globals.  */\n"
449            "struct target_optabs {\n"
450            "  /* Patterns that are used by optabs that are enabled for this target.  */\n"
451            "  bool pat_enable[NUM_OPTAB_PATTERNS];\n"
452            "};\n"
453            "extern void init_all_optabs (struct target_optabs *);\n"
454            "\n"
455            "extern struct target_optabs default_target_optabs;\n"
456            "extern struct target_optabs *this_fn_optabs;\n"
457            "#if SWITCHABLE_TARGET\n"
458            "extern struct target_optabs *this_target_optabs;\n"
459            "#else\n"
460            "#define this_target_optabs (&default_target_optabs)\n"
461            "#endif\n");
462
463   fprintf (s_file,
464            "#include \"config.h\"\n"
465            "#include \"system.h\"\n"
466            "#include \"coretypes.h\"\n"
467            "#include \"tm.h\"\n"
468            "#include \"hash-set.h\"\n"
469            "#include \"machmode.h\"\n"
470            "#include \"vec.h\"\n"
471            "#include \"double-int.h\"\n"
472            "#include \"input.h\"\n"
473            "#include \"alias.h\"\n"
474            "#include \"symtab.h\"\n"
475            "#include \"wide-int.h\"\n"
476            "#include \"inchash.h\"\n"
477            "#include \"tree.h\"\n"
478            "#include \"varasm.h\"\n"
479            "#include \"stor-layout.h\"\n"
480            "#include \"calls.h\"\n"
481            "#include \"rtl.h\"\n"
482            "#include \"predict.h\"\n"
483            "#include \"tm_p.h\"\n"
484            "#include \"flags.h\"\n"
485            "#include \"insn-config.h\"\n"
486            "#include \"hashtab.h\"\n"
487            "#include \"hard-reg-set.h\"\n"
488            "#include \"function.h\"\n"
489            "#include \"statistics.h\"\n"
490            "#include \"real.h\"\n"
491            "#include \"fixed-value.h\"\n"
492            "#include \"expmed.h\"\n"
493            "#include \"dojump.h\"\n"
494            "#include \"explow.h\"\n"
495            "#include \"emit-rtl.h\"\n"
496            "#include \"stmt.h\"\n"
497            "#include \"expr.h\"\n"
498            "#include \"insn-codes.h\"\n"
499            "#include \"optabs.h\"\n"
500            "\n"
501            "struct optab_pat {\n"
502            "  unsigned scode;\n"
503            "  enum insn_code icode;\n"
504            "};\n\n");
505
506   fprintf (s_file,
507            "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
508   for (i = 0; patterns.iterate (i, &p); ++i)
509     fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
510   fprintf (s_file, "};\n\n");
511
512   fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
513   fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
514   for (i = 0; patterns.iterate (i, &p); ++i)
515     fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
516   fprintf (s_file, "}\n\n");
517
518   /* Perform a binary search on a pre-encoded optab+mode*2.  */
519   /* ??? Perhaps even better to generate a minimal perfect hash.
520      Using gperf directly is awkward since it's so geared to working
521      with strings.  Plus we have no visibility into the ordering of
522      the hash entries, which complicates the pat_enable array.  */
523   fprintf (s_file,
524            "static int\n"
525            "lookup_handler (unsigned scode)\n"
526            "{\n"
527            "  int l = 0, h = ARRAY_SIZE (pats), m;\n"
528            "  while (h > l)\n"
529            "    {\n"
530            "      m = (h + l) / 2;\n"
531            "      if (scode == pats[m].scode)\n"
532            "        return m;\n"
533            "      else if (scode < pats[m].scode)\n"
534            "        h = m;\n"
535            "      else\n"
536            "        l = m + 1;\n"
537            "    }\n"
538            "  return -1;\n"
539            "}\n\n");
540
541   fprintf (s_file,
542            "enum insn_code\n"
543            "raw_optab_handler (unsigned scode)\n"
544            "{\n"
545            "  int i = lookup_handler (scode);\n"
546            "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
547            "          ? pats[i].icode : CODE_FOR_nothing);\n"
548            "}\n\n");
549
550   fprintf (s_file,
551            "bool\n"
552            "swap_optab_enable (optab op, machine_mode m, bool set)\n"
553            "{\n"
554            "  unsigned scode = (op << 16) | m;\n"
555            "  int i = lookup_handler (scode);\n"
556            "  if (i >= 0)\n"
557            "    {\n"
558            "      bool ret = this_fn_optabs->pat_enable[i];\n"
559            "      this_fn_optabs->pat_enable[i] = set;\n"
560            "      return ret;\n"
561            "    }\n"
562            "  else\n"
563            "    {\n"
564            "      gcc_assert (!set);\n"
565            "      return false;\n"
566            "    }\n"
567            "}\n\n");
568
569   /* C++ (even G++) does not support (non-trivial) designated initializers.
570      To work around that, generate these arrays programatically rather than
571      by our traditional multiple inclusion of def files.  */
572
573   fprintf (s_file,
574            "const struct convert_optab_libcall_d "
575            "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
576   for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
577     fprintf (s_file, "  { %s, %s },\n", optabs[i].base, optabs[i].libcall);
578   fprintf (s_file, "};\n\n");
579
580   fprintf (s_file,
581            "const struct optab_libcall_d "
582            "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
583   for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
584     fprintf (s_file, "  { %s, %s, %s },\n",
585              optabs[i].suffix, optabs[i].base, optabs[i].libcall);
586   fprintf (s_file, "};\n\n");
587
588   fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
589   for (i = 0; i < n; ++i)
590     fprintf (s_file, "  %s,\n", rtx_upname[optabs[i].fcode]);
591   fprintf (s_file, "};\n\n");
592
593   qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
594
595   fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
596   for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
597     continue;
598   for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
599     {
600       if (j < n && optabs[j].rcode == i)
601         fprintf (s_file, "  %s,\n", optabs[j++].name);
602       else
603         fprintf (s_file, "  unknown_optab,\n");
604     }
605   fprintf (s_file, "};\n\n");
606
607   return (fclose (h_file) == 0 && fclose (s_file) == 0
608           ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
609 }