1/* Generate code to initialize optabs from machine description.
2   Copyright (C) 1993-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
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
8Software Foundation; either version 3, or (at your option) any later
9version.
10
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.
15
16You should have received a copy of the GNU General Public License
17along 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
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.
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
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"
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
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
147
148static vec<pattern> patterns;
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;
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
245static void
246gen_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
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}
279
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}
290
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}
298
299static const char *header_file_name = "init-opinit.h";
300static const char *source_file_name = "init-opinit.c";
301
302static bool
303handle_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
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}
329
330int
331main (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}
610