xref: /dragonfly/contrib/gcc-8.0/gcc/genopinit.c (revision 38fd1498)
1*38fd1498Szrj /* Generate code to initialize optabs from machine description.
2*38fd1498Szrj    Copyright (C) 1993-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj 
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj 
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj 
21*38fd1498Szrj #include "bconfig.h"
22*38fd1498Szrj #include "system.h"
23*38fd1498Szrj #include "coretypes.h"
24*38fd1498Szrj #include "tm.h"
25*38fd1498Szrj #include "rtl.h"
26*38fd1498Szrj #include "errors.h"
27*38fd1498Szrj #include "gensupport.h"
28*38fd1498Szrj 
29*38fd1498Szrj 
30*38fd1498Szrj #define DEF_RTL_EXPR(V, N, X, C) #V,
31*38fd1498Szrj 
32*38fd1498Szrj static const char * const rtx_upname[] = {
33*38fd1498Szrj #include "rtl.def"
34*38fd1498Szrj };
35*38fd1498Szrj 
36*38fd1498Szrj #undef DEF_RTL_EXPR
37*38fd1498Szrj 
38*38fd1498Szrj /* Vector in which to collect insns that match.  */
39*38fd1498Szrj static vec<optab_pattern> patterns;
40*38fd1498Szrj 
41*38fd1498Szrj static void
gen_insn(md_rtx_info * info)42*38fd1498Szrj gen_insn (md_rtx_info *info)
43*38fd1498Szrj {
44*38fd1498Szrj   optab_pattern p;
45*38fd1498Szrj   if (find_optab (&p, XSTR (info->def, 0)))
46*38fd1498Szrj     patterns.safe_push (p);
47*38fd1498Szrj }
48*38fd1498Szrj 
49*38fd1498Szrj static int
pattern_cmp(const void * va,const void * vb)50*38fd1498Szrj pattern_cmp (const void *va, const void *vb)
51*38fd1498Szrj {
52*38fd1498Szrj   const optab_pattern *a = (const optab_pattern *)va;
53*38fd1498Szrj   const optab_pattern *b = (const optab_pattern *)vb;
54*38fd1498Szrj   return a->sort_num - b->sort_num;
55*38fd1498Szrj }
56*38fd1498Szrj 
57*38fd1498Szrj static int
optab_kind_cmp(const void * va,const void * vb)58*38fd1498Szrj optab_kind_cmp (const void *va, const void *vb)
59*38fd1498Szrj {
60*38fd1498Szrj   const optab_def *a = (const optab_def *)va;
61*38fd1498Szrj   const optab_def *b = (const optab_def *)vb;
62*38fd1498Szrj   int diff = a->kind - b->kind;
63*38fd1498Szrj   if (diff == 0)
64*38fd1498Szrj     diff = a->op - b->op;
65*38fd1498Szrj   return diff;
66*38fd1498Szrj }
67*38fd1498Szrj 
68*38fd1498Szrj static int
optab_rcode_cmp(const void * va,const void * vb)69*38fd1498Szrj optab_rcode_cmp (const void *va, const void *vb)
70*38fd1498Szrj {
71*38fd1498Szrj   const optab_def *a = (const optab_def *)va;
72*38fd1498Szrj   const optab_def *b = (const optab_def *)vb;
73*38fd1498Szrj   return a->rcode - b->rcode;
74*38fd1498Szrj }
75*38fd1498Szrj 
76*38fd1498Szrj static const char *header_file_name = "init-opinit.h";
77*38fd1498Szrj static const char *source_file_name = "init-opinit.c";
78*38fd1498Szrj 
79*38fd1498Szrj static bool
handle_arg(const char * arg)80*38fd1498Szrj handle_arg (const char *arg)
81*38fd1498Szrj {
82*38fd1498Szrj   switch (arg[1])
83*38fd1498Szrj     {
84*38fd1498Szrj     case 'h':
85*38fd1498Szrj       header_file_name = &arg[2];
86*38fd1498Szrj       return true;
87*38fd1498Szrj     case 'c':
88*38fd1498Szrj       source_file_name = &arg[2];
89*38fd1498Szrj       return true;
90*38fd1498Szrj     default:
91*38fd1498Szrj       return false;
92*38fd1498Szrj     }
93*38fd1498Szrj }
94*38fd1498Szrj 
95*38fd1498Szrj static FILE *
open_outfile(const char * file_name)96*38fd1498Szrj open_outfile (const char *file_name)
97*38fd1498Szrj {
98*38fd1498Szrj   FILE *f = fopen (file_name, "w");
99*38fd1498Szrj   if (!f)
100*38fd1498Szrj     fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
101*38fd1498Szrj   fprintf (f,
102*38fd1498Szrj 	   "/* Generated automatically by the program `genopinit'\n"
103*38fd1498Szrj 	   "   from the machine description file `md'.  */\n\n");
104*38fd1498Szrj   return f;
105*38fd1498Szrj }
106*38fd1498Szrj 
107*38fd1498Szrj int
main(int argc,const char ** argv)108*38fd1498Szrj main (int argc, const char **argv)
109*38fd1498Szrj {
110*38fd1498Szrj   FILE *h_file, *s_file;
111*38fd1498Szrj   unsigned int i, j, n, last_kind[5];
112*38fd1498Szrj   optab_pattern *p;
113*38fd1498Szrj 
114*38fd1498Szrj   progname = "genopinit";
115*38fd1498Szrj 
116*38fd1498Szrj   if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
117*38fd1498Szrj     fatal ("genopinit range assumptions invalid");
118*38fd1498Szrj 
119*38fd1498Szrj   if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
120*38fd1498Szrj     return (FATAL_EXIT_CODE);
121*38fd1498Szrj 
122*38fd1498Szrj   h_file = open_outfile (header_file_name);
123*38fd1498Szrj   s_file = open_outfile (source_file_name);
124*38fd1498Szrj 
125*38fd1498Szrj   /* Read the machine description.  */
126*38fd1498Szrj   md_rtx_info info;
127*38fd1498Szrj   while (read_md_rtx (&info))
128*38fd1498Szrj     switch (GET_CODE (info.def))
129*38fd1498Szrj       {
130*38fd1498Szrj       case DEFINE_INSN:
131*38fd1498Szrj       case DEFINE_EXPAND:
132*38fd1498Szrj 	gen_insn (&info);
133*38fd1498Szrj 	break;
134*38fd1498Szrj 
135*38fd1498Szrj       default:
136*38fd1498Szrj 	break;
137*38fd1498Szrj       }
138*38fd1498Szrj 
139*38fd1498Szrj   /* Sort the collected patterns.  */
140*38fd1498Szrj   patterns.qsort (pattern_cmp);
141*38fd1498Szrj 
142*38fd1498Szrj   /* Now that we've handled the "extra" patterns, eliminate them from
143*38fd1498Szrj      the optabs array.  That way they don't get in the way below.  */
144*38fd1498Szrj   n = num_optabs;
145*38fd1498Szrj   for (i = 0; i < n; )
146*38fd1498Szrj     if (optabs[i].base == NULL)
147*38fd1498Szrj       optabs[i] = optabs[--n];
148*38fd1498Szrj     else
149*38fd1498Szrj       ++i;
150*38fd1498Szrj 
151*38fd1498Szrj   /* Sort the (real) optabs.  Better than forcing the optabs.def file to
152*38fd1498Szrj      remain sorted by kind.  We also scrogged any real ordering with the
153*38fd1498Szrj      purging of the X patterns above.  */
154*38fd1498Szrj   qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
155*38fd1498Szrj 
156*38fd1498Szrj   fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
157*38fd1498Szrj   fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");
158*38fd1498Szrj 
159*38fd1498Szrj   /* Emit the optab enumeration for the header file.  */
160*38fd1498Szrj   fprintf (h_file, "enum optab_tag {\n");
161*38fd1498Szrj   for (i = j = 0; i < n; ++i)
162*38fd1498Szrj     {
163*38fd1498Szrj       optabs[i].op = i;
164*38fd1498Szrj       fprintf (h_file, "  %s,\n", optabs[i].name);
165*38fd1498Szrj       if (optabs[i].kind != j)
166*38fd1498Szrj 	last_kind[j++] = i - 1;
167*38fd1498Szrj     }
168*38fd1498Szrj   fprintf (h_file, "  FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
169*38fd1498Szrj   fprintf (h_file, "  LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
170*38fd1498Szrj   fprintf (h_file, "  LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
171*38fd1498Szrj   fprintf (h_file, "  FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
172*38fd1498Szrj   fprintf (h_file, "  LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
173*38fd1498Szrj   fprintf (h_file, "  LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
174*38fd1498Szrj   fprintf (h_file, "};\n\n");
175*38fd1498Szrj 
176*38fd1498Szrj   fprintf (h_file, "#define NUM_OPTABS          %u\n", n);
177*38fd1498Szrj   fprintf (h_file, "#define NUM_CONVLIB_OPTABS  %u\n",
178*38fd1498Szrj 	   last_kind[1] - last_kind[0]);
179*38fd1498Szrj   fprintf (h_file, "#define NUM_NORMLIB_OPTABS  %u\n",
180*38fd1498Szrj 	   last_kind[3] - last_kind[2]);
181*38fd1498Szrj   fprintf (h_file, "#define NUM_OPTAB_PATTERNS  %u\n",
182*38fd1498Szrj 	   (unsigned) patterns.length ());
183*38fd1498Szrj 
184*38fd1498Szrj   fprintf (h_file,
185*38fd1498Szrj 	   "typedef enum optab_tag optab;\n"
186*38fd1498Szrj 	   "typedef enum optab_tag convert_optab;\n"
187*38fd1498Szrj 	   "typedef enum optab_tag direct_optab;\n"
188*38fd1498Szrj 	   "\n"
189*38fd1498Szrj 	   "struct optab_libcall_d\n"
190*38fd1498Szrj 	   "{\n"
191*38fd1498Szrj 	   "  char libcall_suffix;\n"
192*38fd1498Szrj 	   "  const char *libcall_basename;\n"
193*38fd1498Szrj 	   "  void (*libcall_gen) (optab, const char *name,\n"
194*38fd1498Szrj 	   "		       char suffix, machine_mode);\n"
195*38fd1498Szrj 	   "};\n"
196*38fd1498Szrj 	   "\n"
197*38fd1498Szrj 	   "struct convert_optab_libcall_d\n"
198*38fd1498Szrj 	   "{\n"
199*38fd1498Szrj 	   "  const char *libcall_basename;\n"
200*38fd1498Szrj 	   "  void (*libcall_gen) (convert_optab, const char *name,\n"
201*38fd1498Szrj 	   "		       machine_mode, machine_mode);\n"
202*38fd1498Szrj 	   "};\n"
203*38fd1498Szrj 	   "\n"
204*38fd1498Szrj 	   "/* Given an enum insn_code, access the function to construct\n"
205*38fd1498Szrj 	   "   the body of that kind of insn.  */\n"
206*38fd1498Szrj 	   "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
207*38fd1498Szrj 	   "\n"
208*38fd1498Szrj 	   "#ifdef NUM_RTX_CODE\n"
209*38fd1498Szrj 	   "/* Contains the optab used for each rtx code, and vice-versa.  */\n"
210*38fd1498Szrj 	   "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
211*38fd1498Szrj 	   "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
212*38fd1498Szrj 	   "\n"
213*38fd1498Szrj 	   "static inline optab\n"
214*38fd1498Szrj 	   "code_to_optab (enum rtx_code code)\n"
215*38fd1498Szrj 	   "{\n"
216*38fd1498Szrj 	   "  return code_to_optab_[code];\n"
217*38fd1498Szrj 	   "}\n"
218*38fd1498Szrj 	   "\n"
219*38fd1498Szrj 	   "static inline enum rtx_code\n"
220*38fd1498Szrj 	   "optab_to_code (optab op)\n"
221*38fd1498Szrj 	   "{\n"
222*38fd1498Szrj 	   "  return optab_to_code_[op];\n"
223*38fd1498Szrj 	   "}\n"
224*38fd1498Szrj 	   "#endif\n"
225*38fd1498Szrj 	   "\n"
226*38fd1498Szrj 	   "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
227*38fd1498Szrj 	   "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
228*38fd1498Szrj 	   "\n"
229*38fd1498Szrj 	   "/* Returns the active icode for the given (encoded) optab.  */\n"
230*38fd1498Szrj 	   "extern enum insn_code raw_optab_handler (unsigned);\n"
231*38fd1498Szrj 	   "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
232*38fd1498Szrj 	   "\n"
233*38fd1498Szrj 	   "/* Target-dependent globals.  */\n"
234*38fd1498Szrj 	   "struct target_optabs {\n"
235*38fd1498Szrj 	   "  /* Patterns that are used by optabs that are enabled for this target.  */\n"
236*38fd1498Szrj 	   "  bool pat_enable[NUM_OPTAB_PATTERNS];\n"
237*38fd1498Szrj 	   "\n"
238*38fd1498Szrj 	   "  /* Cache if the target supports vec_gather_load for at least one vector\n"
239*38fd1498Szrj 	   "     mode.  */\n"
240*38fd1498Szrj 	   "  bool supports_vec_gather_load;\n"
241*38fd1498Szrj 	   "  bool supports_vec_gather_load_cached;\n"
242*38fd1498Szrj 	   "  bool supports_vec_scatter_store;\n"
243*38fd1498Szrj 	   "  bool supports_vec_scatter_store_cached;\n"
244*38fd1498Szrj 	   "};\n"
245*38fd1498Szrj 	   "extern void init_all_optabs (struct target_optabs *);\n"
246*38fd1498Szrj 	   "\n"
247*38fd1498Szrj 	   "extern struct target_optabs default_target_optabs;\n"
248*38fd1498Szrj 	   "extern struct target_optabs *this_fn_optabs;\n"
249*38fd1498Szrj 	   "#if SWITCHABLE_TARGET\n"
250*38fd1498Szrj 	   "extern struct target_optabs *this_target_optabs;\n"
251*38fd1498Szrj 	   "#else\n"
252*38fd1498Szrj 	   "#define this_target_optabs (&default_target_optabs)\n"
253*38fd1498Szrj 	   "#endif\n");
254*38fd1498Szrj 
255*38fd1498Szrj   fprintf (s_file,
256*38fd1498Szrj 	   "#define IN_TARGET_CODE 1\n"
257*38fd1498Szrj 	   "#include \"config.h\"\n"
258*38fd1498Szrj 	   "#include \"system.h\"\n"
259*38fd1498Szrj 	   "#include \"coretypes.h\"\n"
260*38fd1498Szrj 	   "#include \"backend.h\"\n"
261*38fd1498Szrj 	   "#include \"predict.h\"\n"
262*38fd1498Szrj 	   "#include \"tree.h\"\n"
263*38fd1498Szrj 	   "#include \"rtl.h\"\n"
264*38fd1498Szrj 	   "#include \"alias.h\"\n"
265*38fd1498Szrj 	   "#include \"varasm.h\"\n"
266*38fd1498Szrj 	   "#include \"stor-layout.h\"\n"
267*38fd1498Szrj 	   "#include \"calls.h\"\n"
268*38fd1498Szrj 	   "#include \"memmodel.h\"\n"
269*38fd1498Szrj 	   "#include \"tm_p.h\"\n"
270*38fd1498Szrj 	   "#include \"flags.h\"\n"
271*38fd1498Szrj 	   "#include \"insn-config.h\"\n"
272*38fd1498Szrj 	   "#include \"expmed.h\"\n"
273*38fd1498Szrj 	   "#include \"dojump.h\"\n"
274*38fd1498Szrj 	   "#include \"explow.h\"\n"
275*38fd1498Szrj 	   "#include \"emit-rtl.h\"\n"
276*38fd1498Szrj 	   "#include \"stmt.h\"\n"
277*38fd1498Szrj 	   "#include \"expr.h\"\n"
278*38fd1498Szrj 	   "#include \"insn-codes.h\"\n"
279*38fd1498Szrj 	   "#include \"optabs.h\"\n"
280*38fd1498Szrj 	   "\n"
281*38fd1498Szrj 	   "struct optab_pat {\n"
282*38fd1498Szrj 	   "  unsigned scode;\n"
283*38fd1498Szrj 	   "  enum insn_code icode;\n"
284*38fd1498Szrj 	   "};\n\n");
285*38fd1498Szrj 
286*38fd1498Szrj   fprintf (s_file,
287*38fd1498Szrj 	   "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
288*38fd1498Szrj   for (i = 0; patterns.iterate (i, &p); ++i)
289*38fd1498Szrj     fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
290*38fd1498Szrj   fprintf (s_file, "};\n\n");
291*38fd1498Szrj 
292*38fd1498Szrj   fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
293*38fd1498Szrj   fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
294*38fd1498Szrj   for (i = 0; patterns.iterate (i, &p); ++i)
295*38fd1498Szrj     fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
296*38fd1498Szrj   fprintf (s_file, "}\n\n");
297*38fd1498Szrj 
298*38fd1498Szrj   /* Perform a binary search on a pre-encoded optab+mode*2.  */
299*38fd1498Szrj   /* ??? Perhaps even better to generate a minimal perfect hash.
300*38fd1498Szrj      Using gperf directly is awkward since it's so geared to working
301*38fd1498Szrj      with strings.  Plus we have no visibility into the ordering of
302*38fd1498Szrj      the hash entries, which complicates the pat_enable array.  */
303*38fd1498Szrj   fprintf (s_file,
304*38fd1498Szrj 	   "static int\n"
305*38fd1498Szrj 	   "lookup_handler (unsigned scode)\n"
306*38fd1498Szrj 	   "{\n"
307*38fd1498Szrj 	   "  int l = 0, h = ARRAY_SIZE (pats), m;\n"
308*38fd1498Szrj 	   "  while (h > l)\n"
309*38fd1498Szrj 	   "    {\n"
310*38fd1498Szrj 	   "      m = (h + l) / 2;\n"
311*38fd1498Szrj 	   "      if (scode == pats[m].scode)\n"
312*38fd1498Szrj 	   "        return m;\n"
313*38fd1498Szrj 	   "      else if (scode < pats[m].scode)\n"
314*38fd1498Szrj 	   "        h = m;\n"
315*38fd1498Szrj 	   "      else\n"
316*38fd1498Szrj 	   "        l = m + 1;\n"
317*38fd1498Szrj 	   "    }\n"
318*38fd1498Szrj 	   "  return -1;\n"
319*38fd1498Szrj 	   "}\n\n");
320*38fd1498Szrj 
321*38fd1498Szrj   fprintf (s_file,
322*38fd1498Szrj 	   "enum insn_code\n"
323*38fd1498Szrj 	   "raw_optab_handler (unsigned scode)\n"
324*38fd1498Szrj 	   "{\n"
325*38fd1498Szrj 	   "  int i = lookup_handler (scode);\n"
326*38fd1498Szrj 	   "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
327*38fd1498Szrj 	   "          ? pats[i].icode : CODE_FOR_nothing);\n"
328*38fd1498Szrj 	   "}\n\n");
329*38fd1498Szrj 
330*38fd1498Szrj   fprintf (s_file,
331*38fd1498Szrj 	   "bool\n"
332*38fd1498Szrj 	   "swap_optab_enable (optab op, machine_mode m, bool set)\n"
333*38fd1498Szrj 	   "{\n"
334*38fd1498Szrj 	   "  unsigned scode = (op << 16) | m;\n"
335*38fd1498Szrj 	   "  int i = lookup_handler (scode);\n"
336*38fd1498Szrj 	   "  if (i >= 0)\n"
337*38fd1498Szrj 	   "    {\n"
338*38fd1498Szrj 	   "      bool ret = this_fn_optabs->pat_enable[i];\n"
339*38fd1498Szrj 	   "      this_fn_optabs->pat_enable[i] = set;\n"
340*38fd1498Szrj 	   "      return ret;\n"
341*38fd1498Szrj 	   "    }\n"
342*38fd1498Szrj 	   "  else\n"
343*38fd1498Szrj 	   "    {\n"
344*38fd1498Szrj 	   "      gcc_assert (!set);\n"
345*38fd1498Szrj 	   "      return false;\n"
346*38fd1498Szrj 	   "    }\n"
347*38fd1498Szrj 	   "}\n\n");
348*38fd1498Szrj 
349*38fd1498Szrj   /* C++ (even G++) does not support (non-trivial) designated initializers.
350*38fd1498Szrj      To work around that, generate these arrays programatically rather than
351*38fd1498Szrj      by our traditional multiple inclusion of def files.  */
352*38fd1498Szrj 
353*38fd1498Szrj   fprintf (s_file,
354*38fd1498Szrj 	   "const struct convert_optab_libcall_d "
355*38fd1498Szrj 	   "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
356*38fd1498Szrj   for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
357*38fd1498Szrj     fprintf (s_file, "  { %s, %s },\n", optabs[i].base, optabs[i].libcall);
358*38fd1498Szrj   fprintf (s_file, "};\n\n");
359*38fd1498Szrj 
360*38fd1498Szrj   fprintf (s_file,
361*38fd1498Szrj 	   "const struct optab_libcall_d "
362*38fd1498Szrj 	   "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
363*38fd1498Szrj   for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
364*38fd1498Szrj     fprintf (s_file, "  { %s, %s, %s },\n",
365*38fd1498Szrj 	     optabs[i].suffix, optabs[i].base, optabs[i].libcall);
366*38fd1498Szrj   fprintf (s_file, "};\n\n");
367*38fd1498Szrj 
368*38fd1498Szrj   fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
369*38fd1498Szrj   for (i = 0; i < n; ++i)
370*38fd1498Szrj     fprintf (s_file, "  %s,\n", rtx_upname[optabs[i].fcode]);
371*38fd1498Szrj   fprintf (s_file, "};\n\n");
372*38fd1498Szrj 
373*38fd1498Szrj   qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
374*38fd1498Szrj 
375*38fd1498Szrj   fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
376*38fd1498Szrj   for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
377*38fd1498Szrj     continue;
378*38fd1498Szrj   for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
379*38fd1498Szrj     {
380*38fd1498Szrj       if (j < n && optabs[j].rcode == i)
381*38fd1498Szrj 	fprintf (s_file, "  %s,\n", optabs[j++].name);
382*38fd1498Szrj       else
383*38fd1498Szrj 	fprintf (s_file, "  unknown_optab,\n");
384*38fd1498Szrj     }
385*38fd1498Szrj   fprintf (s_file, "};\n\n");
386*38fd1498Szrj 
387*38fd1498Szrj   fprintf (h_file, "#endif\n");
388*38fd1498Szrj   return (fclose (h_file) == 0 && fclose (s_file) == 0
389*38fd1498Szrj 	  ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
390*38fd1498Szrj }
391