1 /* Generate code to initialize optabs from machine description.
2    Copyright (C) 1993-2014 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
match_pattern(pattern * p,const char * name,const char * pat)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
gen_insn(rtx insn)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
pattern_cmp(const void * va,const void * vb)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
optab_kind_cmp(const void * va,const void * vb)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
optab_rcode_cmp(const void * va,const void * vb)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
handle_arg(const char * arg)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 *
open_outfile(const char * file_name)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
main(int argc,char ** argv)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   qsort (patterns.address (), patterns.length (),
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.  */
375   qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
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",
400 	   (unsigned) patterns.length ());
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"
407 	   "#include \"tree.h\"\n"
408 	   "#include \"varasm.h\"\n"
409 	   "#include \"stor-layout.h\"\n"
410 	   "#include \"calls.h\"\n"
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");
425   for (i = 0; patterns.iterate (i, &p); ++i)
426     fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
427   fprintf (s_file, "};\n\n");
428 
429   fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
430   fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
431   for (i = 0; patterns.iterate (i, &p); ++i)
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"
463 	   "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
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"
475 	   "      bool ret = this_fn_optabs->pat_enable[i];\n"
476 	   "      this_fn_optabs->pat_enable[i] = set;\n"
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);
526 }
527