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