xref: /netbsd/external/gpl3/gcc/dist/gcc/genopinit.c (revision dd083157)
1c3d31fe1Smrg /* Generate code to initialize optabs from machine description.
2*dd083157Smrg    Copyright (C) 1993-2020 Free Software Foundation, Inc.
3c3d31fe1Smrg 
4c3d31fe1Smrg This file is part of GCC.
5c3d31fe1Smrg 
6c3d31fe1Smrg GCC is free software; you can redistribute it and/or modify it under
7c3d31fe1Smrg the terms of the GNU General Public License as published by the Free
8c3d31fe1Smrg Software Foundation; either version 3, or (at your option) any later
9c3d31fe1Smrg version.
10c3d31fe1Smrg 
11c3d31fe1Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12c3d31fe1Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13c3d31fe1Smrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14c3d31fe1Smrg for more details.
15c3d31fe1Smrg 
16c3d31fe1Smrg You should have received a copy of the GNU General Public License
17c3d31fe1Smrg along with GCC; see the file COPYING3.  If not see
18c3d31fe1Smrg <http://www.gnu.org/licenses/>.  */
19c3d31fe1Smrg 
20c3d31fe1Smrg 
21c3d31fe1Smrg #include "bconfig.h"
22c3d31fe1Smrg #include "system.h"
23c3d31fe1Smrg #include "coretypes.h"
24c3d31fe1Smrg #include "tm.h"
25c3d31fe1Smrg #include "rtl.h"
26c3d31fe1Smrg #include "errors.h"
27c3d31fe1Smrg #include "gensupport.h"
28c3d31fe1Smrg 
29c3d31fe1Smrg 
30af526226Smrg #define DEF_RTL_EXPR(V, N, X, C) #V,
31c3d31fe1Smrg 
32af526226Smrg static const char * const rtx_upname[] = {
33af526226Smrg #include "rtl.def"
34af526226Smrg };
35c3d31fe1Smrg 
36af526226Smrg #undef DEF_RTL_EXPR
37c3d31fe1Smrg 
38af526226Smrg /* Vector in which to collect insns that match.  */
3963aace61Smrg static vec<optab_pattern> patterns;
40c3d31fe1Smrg 
41af526226Smrg static void
gen_insn(md_rtx_info * info)4263aace61Smrg gen_insn (md_rtx_info *info)
43af526226Smrg {
4463aace61Smrg   optab_pattern p;
4563aace61Smrg   if (find_optab (&p, XSTR (info->def, 0)))
46af526226Smrg     patterns.safe_push (p);
47af526226Smrg }
48af526226Smrg 
49af526226Smrg static int
pattern_cmp(const void * va,const void * vb)50af526226Smrg pattern_cmp (const void *va, const void *vb)
51af526226Smrg {
5263aace61Smrg   const optab_pattern *a = (const optab_pattern *)va;
5363aace61Smrg   const optab_pattern *b = (const optab_pattern *)vb;
54af526226Smrg   return a->sort_num - b->sort_num;
55af526226Smrg }
56af526226Smrg 
57af526226Smrg static int
optab_kind_cmp(const void * va,const void * vb)58af526226Smrg optab_kind_cmp (const void *va, const void *vb)
59af526226Smrg {
60af526226Smrg   const optab_def *a = (const optab_def *)va;
61af526226Smrg   const optab_def *b = (const optab_def *)vb;
62af526226Smrg   int diff = a->kind - b->kind;
63af526226Smrg   if (diff == 0)
64af526226Smrg     diff = a->op - b->op;
65af526226Smrg   return diff;
66af526226Smrg }
67af526226Smrg 
68af526226Smrg static int
optab_rcode_cmp(const void * va,const void * vb)69af526226Smrg optab_rcode_cmp (const void *va, const void *vb)
70af526226Smrg {
71af526226Smrg   const optab_def *a = (const optab_def *)va;
72af526226Smrg   const optab_def *b = (const optab_def *)vb;
73af526226Smrg   return a->rcode - b->rcode;
74af526226Smrg }
75af526226Smrg 
76af526226Smrg static const char *header_file_name = "init-opinit.h";
77af526226Smrg static const char *source_file_name = "init-opinit.c";
78af526226Smrg 
79af526226Smrg static bool
handle_arg(const char * arg)80af526226Smrg handle_arg (const char *arg)
81af526226Smrg {
82af526226Smrg   switch (arg[1])
83af526226Smrg     {
84af526226Smrg     case 'h':
85af526226Smrg       header_file_name = &arg[2];
86af526226Smrg       return true;
87c3d31fe1Smrg     case 'c':
88af526226Smrg       source_file_name = &arg[2];
89af526226Smrg       return true;
90af526226Smrg     default:
91af526226Smrg       return false;
92c3d31fe1Smrg     }
93c3d31fe1Smrg }
94c3d31fe1Smrg 
95af526226Smrg static FILE *
open_outfile(const char * file_name)96af526226Smrg open_outfile (const char *file_name)
97af526226Smrg {
98af526226Smrg   FILE *f = fopen (file_name, "w");
99af526226Smrg   if (!f)
100af526226Smrg     fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
101af526226Smrg   fprintf (f,
102af526226Smrg 	   "/* Generated automatically by the program `genopinit'\n"
103af526226Smrg 	   "   from the machine description file `md'.  */\n\n");
104af526226Smrg   return f;
105c3d31fe1Smrg }
106c3d31fe1Smrg 
10781418a27Smrg /* Declare the maybe_code_for_* function for ONAME, and provide
10881418a27Smrg    an inline definition of the assserting code_for_* wrapper.  */
10981418a27Smrg 
11081418a27Smrg static void
handle_overloaded_code_for(FILE * file,overloaded_name * oname)11181418a27Smrg handle_overloaded_code_for (FILE *file, overloaded_name *oname)
11281418a27Smrg {
11381418a27Smrg   fprintf (file, "\nextern insn_code maybe_code_for_%s (", oname->name);
11481418a27Smrg   for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
11581418a27Smrg     fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
11681418a27Smrg   fprintf (file, ");\n");
11781418a27Smrg 
11881418a27Smrg   fprintf (file, "inline insn_code\ncode_for_%s (", oname->name);
11981418a27Smrg   for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
12081418a27Smrg     fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
12181418a27Smrg   fprintf (file, ")\n{\n  insn_code code = maybe_code_for_%s (", oname->name);
12281418a27Smrg   for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
12381418a27Smrg     fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
12481418a27Smrg   fprintf (file,
12581418a27Smrg 	   ");\n"
12681418a27Smrg 	   "  gcc_assert (code != CODE_FOR_nothing);\n"
12781418a27Smrg 	   "  return code;\n"
12881418a27Smrg 	   "}\n");
12981418a27Smrg }
13081418a27Smrg 
13181418a27Smrg /* Declare the maybe_gen_* function for ONAME, and provide
13281418a27Smrg    an inline definition of the assserting gen_* wrapper.  */
13381418a27Smrg 
13481418a27Smrg static void
handle_overloaded_gen(FILE * file,overloaded_name * oname)13581418a27Smrg handle_overloaded_gen (FILE *file, overloaded_name *oname)
13681418a27Smrg {
137*dd083157Smrg   unsigned HOST_WIDE_INT seen = 0;
138*dd083157Smrg   for (overloaded_instance *instance = oname->first_instance->next;
139*dd083157Smrg        instance; instance = instance->next)
140*dd083157Smrg     {
14181418a27Smrg       pattern_stats stats;
142*dd083157Smrg       get_pattern_stats (&stats, XVEC (instance->insn, 1));
143*dd083157Smrg       unsigned HOST_WIDE_INT mask
144*dd083157Smrg 	= HOST_WIDE_INT_1U << stats.num_generator_args;
145*dd083157Smrg       if (seen & mask)
146*dd083157Smrg 	continue;
147*dd083157Smrg 
148*dd083157Smrg       seen |= mask;
14981418a27Smrg 
15081418a27Smrg       fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
15181418a27Smrg       for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
15281418a27Smrg 	fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
15381418a27Smrg       for (int i = 0; i < stats.num_generator_args; ++i)
15481418a27Smrg 	fprintf (file, ", rtx");
15581418a27Smrg       fprintf (file, ");\n");
15681418a27Smrg 
15781418a27Smrg       fprintf (file, "inline rtx\ngen_%s (", oname->name);
15881418a27Smrg       for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
159*dd083157Smrg 	fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ",
160*dd083157Smrg 		 oname->arg_types[i], i);
16181418a27Smrg       for (int i = 0; i < stats.num_generator_args; ++i)
16281418a27Smrg 	fprintf (file, ", rtx x%d", i);
16381418a27Smrg       fprintf (file, ")\n{\n  rtx res = maybe_gen_%s (", oname->name);
16481418a27Smrg       for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
16581418a27Smrg 	fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
16681418a27Smrg       for (int i = 0; i < stats.num_generator_args; ++i)
16781418a27Smrg 	fprintf (file, ", x%d", i);
16881418a27Smrg       fprintf (file,
16981418a27Smrg 	       ");\n"
17081418a27Smrg 	       "  gcc_assert (res);\n"
17181418a27Smrg 	       "  return res;\n"
17281418a27Smrg 	       "}\n");
17381418a27Smrg     }
174*dd083157Smrg }
17581418a27Smrg 
176c3d31fe1Smrg int
main(int argc,const char ** argv)1776a5c9aabSmrg main (int argc, const char **argv)
178c3d31fe1Smrg {
179af526226Smrg   FILE *h_file, *s_file;
180af526226Smrg   unsigned int i, j, n, last_kind[5];
18163aace61Smrg   optab_pattern *p;
182c3d31fe1Smrg 
183c3d31fe1Smrg   progname = "genopinit";
184c3d31fe1Smrg 
185af526226Smrg   if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
186af526226Smrg     fatal ("genopinit range assumptions invalid");
187af526226Smrg 
188af526226Smrg   if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
189c3d31fe1Smrg     return (FATAL_EXIT_CODE);
190c3d31fe1Smrg 
191af526226Smrg   h_file = open_outfile (header_file_name);
192af526226Smrg   s_file = open_outfile (source_file_name);
193c3d31fe1Smrg 
194c3d31fe1Smrg   /* Read the machine description.  */
19563aace61Smrg   md_rtx_info info;
19663aace61Smrg   while (read_md_rtx (&info))
19763aace61Smrg     switch (GET_CODE (info.def))
198c3d31fe1Smrg       {
19963aace61Smrg       case DEFINE_INSN:
20063aace61Smrg       case DEFINE_EXPAND:
20163aace61Smrg 	gen_insn (&info);
202c3d31fe1Smrg 	break;
20363aace61Smrg 
20463aace61Smrg       default:
20563aace61Smrg 	break;
206c3d31fe1Smrg       }
207c3d31fe1Smrg 
208af526226Smrg   /* Sort the collected patterns.  */
2095ef59e75Smrg   patterns.qsort (pattern_cmp);
210c3d31fe1Smrg 
211af526226Smrg   /* Now that we've handled the "extra" patterns, eliminate them from
212af526226Smrg      the optabs array.  That way they don't get in the way below.  */
21363aace61Smrg   n = num_optabs;
214af526226Smrg   for (i = 0; i < n; )
215af526226Smrg     if (optabs[i].base == NULL)
216af526226Smrg       optabs[i] = optabs[--n];
217af526226Smrg     else
218af526226Smrg       ++i;
219af526226Smrg 
220af526226Smrg   /* Sort the (real) optabs.  Better than forcing the optabs.def file to
221af526226Smrg      remain sorted by kind.  We also scrogged any real ordering with the
222af526226Smrg      purging of the X patterns above.  */
223af526226Smrg   qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
224af526226Smrg 
22563aace61Smrg   fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
22663aace61Smrg   fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");
22763aace61Smrg 
228af526226Smrg   /* Emit the optab enumeration for the header file.  */
229af526226Smrg   fprintf (h_file, "enum optab_tag {\n");
230af526226Smrg   for (i = j = 0; i < n; ++i)
231af526226Smrg     {
232af526226Smrg       optabs[i].op = i;
233af526226Smrg       fprintf (h_file, "  %s,\n", optabs[i].name);
234af526226Smrg       if (optabs[i].kind != j)
235af526226Smrg 	last_kind[j++] = i - 1;
236af526226Smrg     }
237af526226Smrg   fprintf (h_file, "  FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
238af526226Smrg   fprintf (h_file, "  LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
239af526226Smrg   fprintf (h_file, "  LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
240af526226Smrg   fprintf (h_file, "  FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
241af526226Smrg   fprintf (h_file, "  LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
242af526226Smrg   fprintf (h_file, "  LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
243af526226Smrg   fprintf (h_file, "};\n\n");
244af526226Smrg 
245af526226Smrg   fprintf (h_file, "#define NUM_OPTABS          %u\n", n);
246af526226Smrg   fprintf (h_file, "#define NUM_CONVLIB_OPTABS  %u\n",
247af526226Smrg 	   last_kind[1] - last_kind[0]);
248af526226Smrg   fprintf (h_file, "#define NUM_NORMLIB_OPTABS  %u\n",
249af526226Smrg 	   last_kind[3] - last_kind[2]);
250af526226Smrg   fprintf (h_file, "#define NUM_OPTAB_PATTERNS  %u\n",
251af526226Smrg 	   (unsigned) patterns.length ());
252af526226Smrg 
2535ef59e75Smrg   fprintf (h_file,
2545ef59e75Smrg 	   "typedef enum optab_tag optab;\n"
2555ef59e75Smrg 	   "typedef enum optab_tag convert_optab;\n"
2565ef59e75Smrg 	   "typedef enum optab_tag direct_optab;\n"
2575ef59e75Smrg 	   "\n"
2585ef59e75Smrg 	   "struct optab_libcall_d\n"
2595ef59e75Smrg 	   "{\n"
2605ef59e75Smrg 	   "  char libcall_suffix;\n"
2615ef59e75Smrg 	   "  const char *libcall_basename;\n"
2625ef59e75Smrg 	   "  void (*libcall_gen) (optab, const char *name,\n"
2635ef59e75Smrg 	   "		       char suffix, machine_mode);\n"
2645ef59e75Smrg 	   "};\n"
2655ef59e75Smrg 	   "\n"
2665ef59e75Smrg 	   "struct convert_optab_libcall_d\n"
2675ef59e75Smrg 	   "{\n"
2685ef59e75Smrg 	   "  const char *libcall_basename;\n"
2695ef59e75Smrg 	   "  void (*libcall_gen) (convert_optab, const char *name,\n"
2705ef59e75Smrg 	   "		       machine_mode, machine_mode);\n"
2715ef59e75Smrg 	   "};\n"
2725ef59e75Smrg 	   "\n"
2735ef59e75Smrg 	   "/* Given an enum insn_code, access the function to construct\n"
2745ef59e75Smrg 	   "   the body of that kind of insn.  */\n"
2755ef59e75Smrg 	   "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
2765ef59e75Smrg 	   "\n"
27763aace61Smrg 	   "#ifdef NUM_RTX_CODE\n"
2785ef59e75Smrg 	   "/* Contains the optab used for each rtx code, and vice-versa.  */\n"
2795ef59e75Smrg 	   "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
2805ef59e75Smrg 	   "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
2815ef59e75Smrg 	   "\n"
2825ef59e75Smrg 	   "static inline optab\n"
2835ef59e75Smrg 	   "code_to_optab (enum rtx_code code)\n"
2845ef59e75Smrg 	   "{\n"
2855ef59e75Smrg 	   "  return code_to_optab_[code];\n"
2865ef59e75Smrg 	   "}\n"
2875ef59e75Smrg 	   "\n"
2885ef59e75Smrg 	   "static inline enum rtx_code\n"
2895ef59e75Smrg 	   "optab_to_code (optab op)\n"
2905ef59e75Smrg 	   "{\n"
2915ef59e75Smrg 	   "  return optab_to_code_[op];\n"
29281418a27Smrg 	   "}\n");
29381418a27Smrg 
29481418a27Smrg   for (overloaded_name *oname = rtx_reader_ptr->get_overloads ();
29581418a27Smrg        oname; oname = oname->next)
29681418a27Smrg     {
29781418a27Smrg       handle_overloaded_code_for (h_file, oname);
29881418a27Smrg       handle_overloaded_gen (h_file, oname);
29981418a27Smrg     }
30081418a27Smrg 
30181418a27Smrg   fprintf (h_file,
30263aace61Smrg 	   "#endif\n"
3035ef59e75Smrg 	   "\n"
3045ef59e75Smrg 	   "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
3055ef59e75Smrg 	   "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
3065ef59e75Smrg 	   "\n"
3075ef59e75Smrg 	   "/* Returns the active icode for the given (encoded) optab.  */\n"
3085ef59e75Smrg 	   "extern enum insn_code raw_optab_handler (unsigned);\n"
3095ef59e75Smrg 	   "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
3105ef59e75Smrg 	   "\n"
3115ef59e75Smrg 	   "/* Target-dependent globals.  */\n"
3125ef59e75Smrg 	   "struct target_optabs {\n"
3135ef59e75Smrg 	   "  /* Patterns that are used by optabs that are enabled for this target.  */\n"
3145ef59e75Smrg 	   "  bool pat_enable[NUM_OPTAB_PATTERNS];\n"
3153903d7f3Smrg 	   "\n"
3163903d7f3Smrg 	   "  /* Cache if the target supports vec_gather_load for at least one vector\n"
3173903d7f3Smrg 	   "     mode.  */\n"
3183903d7f3Smrg 	   "  bool supports_vec_gather_load;\n"
3193903d7f3Smrg 	   "  bool supports_vec_gather_load_cached;\n"
3203903d7f3Smrg 	   "  bool supports_vec_scatter_store;\n"
3213903d7f3Smrg 	   "  bool supports_vec_scatter_store_cached;\n"
3225ef59e75Smrg 	   "};\n"
3235ef59e75Smrg 	   "extern void init_all_optabs (struct target_optabs *);\n"
3245ef59e75Smrg 	   "\n"
3255ef59e75Smrg 	   "extern struct target_optabs default_target_optabs;\n"
3265ef59e75Smrg 	   "extern struct target_optabs *this_fn_optabs;\n"
3275ef59e75Smrg 	   "#if SWITCHABLE_TARGET\n"
3285ef59e75Smrg 	   "extern struct target_optabs *this_target_optabs;\n"
3295ef59e75Smrg 	   "#else\n"
3305ef59e75Smrg 	   "#define this_target_optabs (&default_target_optabs)\n"
3315ef59e75Smrg 	   "#endif\n");
3325ef59e75Smrg 
333af526226Smrg   fprintf (s_file,
3343903d7f3Smrg 	   "#define IN_TARGET_CODE 1\n"
335af526226Smrg 	   "#include \"config.h\"\n"
336af526226Smrg 	   "#include \"system.h\"\n"
337af526226Smrg 	   "#include \"coretypes.h\"\n"
33863aace61Smrg 	   "#include \"backend.h\"\n"
33963aace61Smrg 	   "#include \"predict.h\"\n"
3405ef59e75Smrg 	   "#include \"tree.h\"\n"
34163aace61Smrg 	   "#include \"rtl.h\"\n"
34263aace61Smrg 	   "#include \"alias.h\"\n"
3435ef59e75Smrg 	   "#include \"varasm.h\"\n"
3445ef59e75Smrg 	   "#include \"stor-layout.h\"\n"
3455ef59e75Smrg 	   "#include \"calls.h\"\n"
3466a5c9aabSmrg 	   "#include \"memmodel.h\"\n"
347af526226Smrg 	   "#include \"tm_p.h\"\n"
348af526226Smrg 	   "#include \"flags.h\"\n"
349af526226Smrg 	   "#include \"insn-config.h\"\n"
3505ef59e75Smrg 	   "#include \"expmed.h\"\n"
3515ef59e75Smrg 	   "#include \"dojump.h\"\n"
3525ef59e75Smrg 	   "#include \"explow.h\"\n"
3535ef59e75Smrg 	   "#include \"emit-rtl.h\"\n"
3545ef59e75Smrg 	   "#include \"stmt.h\"\n"
355af526226Smrg 	   "#include \"expr.h\"\n"
3565ef59e75Smrg 	   "#include \"insn-codes.h\"\n"
357af526226Smrg 	   "#include \"optabs.h\"\n"
358af526226Smrg 	   "\n"
359af526226Smrg 	   "struct optab_pat {\n"
360af526226Smrg 	   "  unsigned scode;\n"
361af526226Smrg 	   "  enum insn_code icode;\n"
362af526226Smrg 	   "};\n\n");
363af526226Smrg 
364af526226Smrg   fprintf (s_file,
365af526226Smrg 	   "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
366af526226Smrg   for (i = 0; patterns.iterate (i, &p); ++i)
367af526226Smrg     fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
368af526226Smrg   fprintf (s_file, "};\n\n");
369af526226Smrg 
370af526226Smrg   fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
371af526226Smrg   fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
372af526226Smrg   for (i = 0; patterns.iterate (i, &p); ++i)
373af526226Smrg     fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
374af526226Smrg   fprintf (s_file, "}\n\n");
375af526226Smrg 
376af526226Smrg   /* Perform a binary search on a pre-encoded optab+mode*2.  */
377af526226Smrg   /* ??? Perhaps even better to generate a minimal perfect hash.
378af526226Smrg      Using gperf directly is awkward since it's so geared to working
379af526226Smrg      with strings.  Plus we have no visibility into the ordering of
380af526226Smrg      the hash entries, which complicates the pat_enable array.  */
381af526226Smrg   fprintf (s_file,
382af526226Smrg 	   "static int\n"
383af526226Smrg 	   "lookup_handler (unsigned scode)\n"
384af526226Smrg 	   "{\n"
385af526226Smrg 	   "  int l = 0, h = ARRAY_SIZE (pats), m;\n"
386af526226Smrg 	   "  while (h > l)\n"
387af526226Smrg 	   "    {\n"
388af526226Smrg 	   "      m = (h + l) / 2;\n"
389af526226Smrg 	   "      if (scode == pats[m].scode)\n"
390af526226Smrg 	   "        return m;\n"
391af526226Smrg 	   "      else if (scode < pats[m].scode)\n"
392af526226Smrg 	   "        h = m;\n"
393af526226Smrg 	   "      else\n"
394af526226Smrg 	   "        l = m + 1;\n"
395af526226Smrg 	   "    }\n"
396af526226Smrg 	   "  return -1;\n"
397af526226Smrg 	   "}\n\n");
398af526226Smrg 
399af526226Smrg   fprintf (s_file,
400af526226Smrg 	   "enum insn_code\n"
401af526226Smrg 	   "raw_optab_handler (unsigned scode)\n"
402af526226Smrg 	   "{\n"
403af526226Smrg 	   "  int i = lookup_handler (scode);\n"
404af526226Smrg 	   "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
405af526226Smrg 	   "          ? pats[i].icode : CODE_FOR_nothing);\n"
406af526226Smrg 	   "}\n\n");
407af526226Smrg 
408af526226Smrg   fprintf (s_file,
409af526226Smrg 	   "bool\n"
4105ef59e75Smrg 	   "swap_optab_enable (optab op, machine_mode m, bool set)\n"
411af526226Smrg 	   "{\n"
412af526226Smrg 	   "  unsigned scode = (op << 16) | m;\n"
413af526226Smrg 	   "  int i = lookup_handler (scode);\n"
414af526226Smrg 	   "  if (i >= 0)\n"
415af526226Smrg 	   "    {\n"
416af526226Smrg 	   "      bool ret = this_fn_optabs->pat_enable[i];\n"
417af526226Smrg 	   "      this_fn_optabs->pat_enable[i] = set;\n"
418af526226Smrg 	   "      return ret;\n"
419af526226Smrg 	   "    }\n"
420af526226Smrg 	   "  else\n"
421af526226Smrg 	   "    {\n"
422af526226Smrg 	   "      gcc_assert (!set);\n"
423af526226Smrg 	   "      return false;\n"
424af526226Smrg 	   "    }\n"
425af526226Smrg 	   "}\n\n");
426af526226Smrg 
427af526226Smrg   /* C++ (even G++) does not support (non-trivial) designated initializers.
428af526226Smrg      To work around that, generate these arrays programatically rather than
429af526226Smrg      by our traditional multiple inclusion of def files.  */
430af526226Smrg 
431af526226Smrg   fprintf (s_file,
432af526226Smrg 	   "const struct convert_optab_libcall_d "
433af526226Smrg 	   "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
434af526226Smrg   for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
435af526226Smrg     fprintf (s_file, "  { %s, %s },\n", optabs[i].base, optabs[i].libcall);
436af526226Smrg   fprintf (s_file, "};\n\n");
437af526226Smrg 
438af526226Smrg   fprintf (s_file,
439af526226Smrg 	   "const struct optab_libcall_d "
440af526226Smrg 	   "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
441af526226Smrg   for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
442af526226Smrg     fprintf (s_file, "  { %s, %s, %s },\n",
443af526226Smrg 	     optabs[i].suffix, optabs[i].base, optabs[i].libcall);
444af526226Smrg   fprintf (s_file, "};\n\n");
445af526226Smrg 
446af526226Smrg   fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
447af526226Smrg   for (i = 0; i < n; ++i)
448af526226Smrg     fprintf (s_file, "  %s,\n", rtx_upname[optabs[i].fcode]);
449af526226Smrg   fprintf (s_file, "};\n\n");
450af526226Smrg 
451af526226Smrg   qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
452af526226Smrg 
453af526226Smrg   fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
454af526226Smrg   for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
455af526226Smrg     continue;
456af526226Smrg   for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
457af526226Smrg     {
458af526226Smrg       if (j < n && optabs[j].rcode == i)
459af526226Smrg 	fprintf (s_file, "  %s,\n", optabs[j++].name);
460af526226Smrg       else
461af526226Smrg 	fprintf (s_file, "  unknown_optab,\n");
462af526226Smrg     }
463af526226Smrg   fprintf (s_file, "};\n\n");
464af526226Smrg 
46563aace61Smrg   fprintf (h_file, "#endif\n");
466af526226Smrg   return (fclose (h_file) == 0 && fclose (s_file) == 0
467af526226Smrg 	  ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
468c3d31fe1Smrg }
469