11debfc3dSmrg /* Generate code to initialize optabs from machine description.
2*8feb0f0bSmrg Copyright (C) 1993-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3. If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>. */
191debfc3dSmrg
201debfc3dSmrg
211debfc3dSmrg #include "bconfig.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "tm.h"
251debfc3dSmrg #include "rtl.h"
261debfc3dSmrg #include "errors.h"
271debfc3dSmrg #include "gensupport.h"
281debfc3dSmrg
291debfc3dSmrg
301debfc3dSmrg #define DEF_RTL_EXPR(V, N, X, C) #V,
311debfc3dSmrg
321debfc3dSmrg static const char * const rtx_upname[] = {
331debfc3dSmrg #include "rtl.def"
341debfc3dSmrg };
351debfc3dSmrg
361debfc3dSmrg #undef DEF_RTL_EXPR
371debfc3dSmrg
381debfc3dSmrg /* Vector in which to collect insns that match. */
391debfc3dSmrg static vec<optab_pattern> patterns;
401debfc3dSmrg
411debfc3dSmrg static void
gen_insn(md_rtx_info * info)421debfc3dSmrg gen_insn (md_rtx_info *info)
431debfc3dSmrg {
441debfc3dSmrg optab_pattern p;
451debfc3dSmrg if (find_optab (&p, XSTR (info->def, 0)))
461debfc3dSmrg patterns.safe_push (p);
471debfc3dSmrg }
481debfc3dSmrg
491debfc3dSmrg static int
pattern_cmp(const void * va,const void * vb)501debfc3dSmrg pattern_cmp (const void *va, const void *vb)
511debfc3dSmrg {
521debfc3dSmrg const optab_pattern *a = (const optab_pattern *)va;
531debfc3dSmrg const optab_pattern *b = (const optab_pattern *)vb;
541debfc3dSmrg return a->sort_num - b->sort_num;
551debfc3dSmrg }
561debfc3dSmrg
571debfc3dSmrg static int
optab_kind_cmp(const void * va,const void * vb)581debfc3dSmrg optab_kind_cmp (const void *va, const void *vb)
591debfc3dSmrg {
601debfc3dSmrg const optab_def *a = (const optab_def *)va;
611debfc3dSmrg const optab_def *b = (const optab_def *)vb;
621debfc3dSmrg int diff = a->kind - b->kind;
631debfc3dSmrg if (diff == 0)
641debfc3dSmrg diff = a->op - b->op;
651debfc3dSmrg return diff;
661debfc3dSmrg }
671debfc3dSmrg
681debfc3dSmrg static int
optab_rcode_cmp(const void * va,const void * vb)691debfc3dSmrg optab_rcode_cmp (const void *va, const void *vb)
701debfc3dSmrg {
711debfc3dSmrg const optab_def *a = (const optab_def *)va;
721debfc3dSmrg const optab_def *b = (const optab_def *)vb;
731debfc3dSmrg return a->rcode - b->rcode;
741debfc3dSmrg }
751debfc3dSmrg
761debfc3dSmrg static const char *header_file_name = "init-opinit.h";
771debfc3dSmrg static const char *source_file_name = "init-opinit.c";
781debfc3dSmrg
791debfc3dSmrg static bool
handle_arg(const char * arg)801debfc3dSmrg handle_arg (const char *arg)
811debfc3dSmrg {
821debfc3dSmrg switch (arg[1])
831debfc3dSmrg {
841debfc3dSmrg case 'h':
851debfc3dSmrg header_file_name = &arg[2];
861debfc3dSmrg return true;
871debfc3dSmrg case 'c':
881debfc3dSmrg source_file_name = &arg[2];
891debfc3dSmrg return true;
901debfc3dSmrg default:
911debfc3dSmrg return false;
921debfc3dSmrg }
931debfc3dSmrg }
941debfc3dSmrg
951debfc3dSmrg static FILE *
open_outfile(const char * file_name)961debfc3dSmrg open_outfile (const char *file_name)
971debfc3dSmrg {
981debfc3dSmrg FILE *f = fopen (file_name, "w");
991debfc3dSmrg if (!f)
1001debfc3dSmrg fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
1011debfc3dSmrg fprintf (f,
1021debfc3dSmrg "/* Generated automatically by the program `genopinit'\n"
1031debfc3dSmrg " from the machine description file `md'. */\n\n");
1041debfc3dSmrg return f;
1051debfc3dSmrg }
1061debfc3dSmrg
107c0a68be4Smrg /* Declare the maybe_code_for_* function for ONAME, and provide
108c0a68be4Smrg an inline definition of the assserting code_for_* wrapper. */
109c0a68be4Smrg
110c0a68be4Smrg static void
handle_overloaded_code_for(FILE * file,overloaded_name * oname)111c0a68be4Smrg handle_overloaded_code_for (FILE *file, overloaded_name *oname)
112c0a68be4Smrg {
113c0a68be4Smrg fprintf (file, "\nextern insn_code maybe_code_for_%s (", oname->name);
114c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
115c0a68be4Smrg fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
116c0a68be4Smrg fprintf (file, ");\n");
117c0a68be4Smrg
118c0a68be4Smrg fprintf (file, "inline insn_code\ncode_for_%s (", oname->name);
119c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
120c0a68be4Smrg fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
121c0a68be4Smrg fprintf (file, ")\n{\n insn_code code = maybe_code_for_%s (", oname->name);
122c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
123c0a68be4Smrg fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
124c0a68be4Smrg fprintf (file,
125c0a68be4Smrg ");\n"
126c0a68be4Smrg " gcc_assert (code != CODE_FOR_nothing);\n"
127c0a68be4Smrg " return code;\n"
128c0a68be4Smrg "}\n");
129c0a68be4Smrg }
130c0a68be4Smrg
131c0a68be4Smrg /* Declare the maybe_gen_* function for ONAME, and provide
132c0a68be4Smrg an inline definition of the assserting gen_* wrapper. */
133c0a68be4Smrg
134c0a68be4Smrg static void
handle_overloaded_gen(FILE * file,overloaded_name * oname)135c0a68be4Smrg handle_overloaded_gen (FILE *file, overloaded_name *oname)
136c0a68be4Smrg {
137*8feb0f0bSmrg unsigned HOST_WIDE_INT seen = 0;
138*8feb0f0bSmrg for (overloaded_instance *instance = oname->first_instance->next;
139*8feb0f0bSmrg instance; instance = instance->next)
140*8feb0f0bSmrg {
141c0a68be4Smrg pattern_stats stats;
142*8feb0f0bSmrg get_pattern_stats (&stats, XVEC (instance->insn, 1));
143*8feb0f0bSmrg unsigned HOST_WIDE_INT mask
144*8feb0f0bSmrg = HOST_WIDE_INT_1U << stats.num_generator_args;
145*8feb0f0bSmrg if (seen & mask)
146*8feb0f0bSmrg continue;
147*8feb0f0bSmrg
148*8feb0f0bSmrg seen |= mask;
149c0a68be4Smrg
150c0a68be4Smrg fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
151c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
152c0a68be4Smrg fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
153c0a68be4Smrg for (int i = 0; i < stats.num_generator_args; ++i)
154c0a68be4Smrg fprintf (file, ", rtx");
155c0a68be4Smrg fprintf (file, ");\n");
156c0a68be4Smrg
157c0a68be4Smrg fprintf (file, "inline rtx\ngen_%s (", oname->name);
158c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
159*8feb0f0bSmrg fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ",
160*8feb0f0bSmrg oname->arg_types[i], i);
161c0a68be4Smrg for (int i = 0; i < stats.num_generator_args; ++i)
162c0a68be4Smrg fprintf (file, ", rtx x%d", i);
163c0a68be4Smrg fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
164c0a68be4Smrg for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
165c0a68be4Smrg fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
166c0a68be4Smrg for (int i = 0; i < stats.num_generator_args; ++i)
167c0a68be4Smrg fprintf (file, ", x%d", i);
168c0a68be4Smrg fprintf (file,
169c0a68be4Smrg ");\n"
170c0a68be4Smrg " gcc_assert (res);\n"
171c0a68be4Smrg " return res;\n"
172c0a68be4Smrg "}\n");
173c0a68be4Smrg }
174*8feb0f0bSmrg }
175c0a68be4Smrg
1761debfc3dSmrg int
main(int argc,const char ** argv)1771debfc3dSmrg main (int argc, const char **argv)
1781debfc3dSmrg {
1791debfc3dSmrg FILE *h_file, *s_file;
1801debfc3dSmrg unsigned int i, j, n, last_kind[5];
1811debfc3dSmrg optab_pattern *p;
1821debfc3dSmrg
1831debfc3dSmrg progname = "genopinit";
1841debfc3dSmrg
1851debfc3dSmrg if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
1861debfc3dSmrg fatal ("genopinit range assumptions invalid");
1871debfc3dSmrg
1881debfc3dSmrg if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
1891debfc3dSmrg return (FATAL_EXIT_CODE);
1901debfc3dSmrg
1911debfc3dSmrg h_file = open_outfile (header_file_name);
1921debfc3dSmrg s_file = open_outfile (source_file_name);
1931debfc3dSmrg
1941debfc3dSmrg /* Read the machine description. */
1951debfc3dSmrg md_rtx_info info;
1961debfc3dSmrg while (read_md_rtx (&info))
1971debfc3dSmrg switch (GET_CODE (info.def))
1981debfc3dSmrg {
1991debfc3dSmrg case DEFINE_INSN:
2001debfc3dSmrg case DEFINE_EXPAND:
2011debfc3dSmrg gen_insn (&info);
2021debfc3dSmrg break;
2031debfc3dSmrg
2041debfc3dSmrg default:
2051debfc3dSmrg break;
2061debfc3dSmrg }
2071debfc3dSmrg
2081debfc3dSmrg /* Sort the collected patterns. */
2091debfc3dSmrg patterns.qsort (pattern_cmp);
2101debfc3dSmrg
2111debfc3dSmrg /* Now that we've handled the "extra" patterns, eliminate them from
2121debfc3dSmrg the optabs array. That way they don't get in the way below. */
2131debfc3dSmrg n = num_optabs;
2141debfc3dSmrg for (i = 0; i < n; )
2151debfc3dSmrg if (optabs[i].base == NULL)
2161debfc3dSmrg optabs[i] = optabs[--n];
2171debfc3dSmrg else
2181debfc3dSmrg ++i;
2191debfc3dSmrg
2201debfc3dSmrg /* Sort the (real) optabs. Better than forcing the optabs.def file to
2211debfc3dSmrg remain sorted by kind. We also scrogged any real ordering with the
2221debfc3dSmrg purging of the X patterns above. */
2231debfc3dSmrg qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
2241debfc3dSmrg
2251debfc3dSmrg fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
2261debfc3dSmrg fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");
2271debfc3dSmrg
2281debfc3dSmrg /* Emit the optab enumeration for the header file. */
2291debfc3dSmrg fprintf (h_file, "enum optab_tag {\n");
2301debfc3dSmrg for (i = j = 0; i < n; ++i)
2311debfc3dSmrg {
2321debfc3dSmrg optabs[i].op = i;
2331debfc3dSmrg fprintf (h_file, " %s,\n", optabs[i].name);
2341debfc3dSmrg if (optabs[i].kind != j)
2351debfc3dSmrg last_kind[j++] = i - 1;
2361debfc3dSmrg }
2371debfc3dSmrg fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
2381debfc3dSmrg fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
2391debfc3dSmrg fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
2401debfc3dSmrg fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
2411debfc3dSmrg fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
2421debfc3dSmrg fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
2431debfc3dSmrg fprintf (h_file, "};\n\n");
2441debfc3dSmrg
2451debfc3dSmrg fprintf (h_file, "#define NUM_OPTABS %u\n", n);
2461debfc3dSmrg fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
2471debfc3dSmrg last_kind[1] - last_kind[0]);
2481debfc3dSmrg fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
2491debfc3dSmrg last_kind[3] - last_kind[2]);
2501debfc3dSmrg fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
2511debfc3dSmrg (unsigned) patterns.length ());
2521debfc3dSmrg
2531debfc3dSmrg fprintf (h_file,
2541debfc3dSmrg "typedef enum optab_tag optab;\n"
2551debfc3dSmrg "typedef enum optab_tag convert_optab;\n"
2561debfc3dSmrg "typedef enum optab_tag direct_optab;\n"
2571debfc3dSmrg "\n"
2581debfc3dSmrg "struct optab_libcall_d\n"
2591debfc3dSmrg "{\n"
2601debfc3dSmrg " char libcall_suffix;\n"
2611debfc3dSmrg " const char *libcall_basename;\n"
2621debfc3dSmrg " void (*libcall_gen) (optab, const char *name,\n"
2631debfc3dSmrg " char suffix, machine_mode);\n"
2641debfc3dSmrg "};\n"
2651debfc3dSmrg "\n"
2661debfc3dSmrg "struct convert_optab_libcall_d\n"
2671debfc3dSmrg "{\n"
2681debfc3dSmrg " const char *libcall_basename;\n"
2691debfc3dSmrg " void (*libcall_gen) (convert_optab, const char *name,\n"
2701debfc3dSmrg " machine_mode, machine_mode);\n"
2711debfc3dSmrg "};\n"
2721debfc3dSmrg "\n"
2731debfc3dSmrg "/* Given an enum insn_code, access the function to construct\n"
2741debfc3dSmrg " the body of that kind of insn. */\n"
2751debfc3dSmrg "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
2761debfc3dSmrg "\n"
2771debfc3dSmrg "#ifdef NUM_RTX_CODE\n"
2781debfc3dSmrg "/* Contains the optab used for each rtx code, and vice-versa. */\n"
2791debfc3dSmrg "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
2801debfc3dSmrg "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
2811debfc3dSmrg "\n"
2821debfc3dSmrg "static inline optab\n"
2831debfc3dSmrg "code_to_optab (enum rtx_code code)\n"
2841debfc3dSmrg "{\n"
2851debfc3dSmrg " return code_to_optab_[code];\n"
2861debfc3dSmrg "}\n"
2871debfc3dSmrg "\n"
2881debfc3dSmrg "static inline enum rtx_code\n"
2891debfc3dSmrg "optab_to_code (optab op)\n"
2901debfc3dSmrg "{\n"
2911debfc3dSmrg " return optab_to_code_[op];\n"
292c0a68be4Smrg "}\n");
293c0a68be4Smrg
294c0a68be4Smrg for (overloaded_name *oname = rtx_reader_ptr->get_overloads ();
295c0a68be4Smrg oname; oname = oname->next)
296c0a68be4Smrg {
297c0a68be4Smrg handle_overloaded_code_for (h_file, oname);
298c0a68be4Smrg handle_overloaded_gen (h_file, oname);
299c0a68be4Smrg }
300c0a68be4Smrg
301c0a68be4Smrg fprintf (h_file,
3021debfc3dSmrg "#endif\n"
3031debfc3dSmrg "\n"
3041debfc3dSmrg "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
3051debfc3dSmrg "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
3061debfc3dSmrg "\n"
3071debfc3dSmrg "/* Returns the active icode for the given (encoded) optab. */\n"
3081debfc3dSmrg "extern enum insn_code raw_optab_handler (unsigned);\n"
3091debfc3dSmrg "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
3101debfc3dSmrg "\n"
3111debfc3dSmrg "/* Target-dependent globals. */\n"
3121debfc3dSmrg "struct target_optabs {\n"
3131debfc3dSmrg " /* Patterns that are used by optabs that are enabled for this target. */\n"
3141debfc3dSmrg " bool pat_enable[NUM_OPTAB_PATTERNS];\n"
315a2dc1f3fSmrg "\n"
316a2dc1f3fSmrg " /* Cache if the target supports vec_gather_load for at least one vector\n"
317a2dc1f3fSmrg " mode. */\n"
318a2dc1f3fSmrg " bool supports_vec_gather_load;\n"
319a2dc1f3fSmrg " bool supports_vec_gather_load_cached;\n"
320a2dc1f3fSmrg " bool supports_vec_scatter_store;\n"
321a2dc1f3fSmrg " bool supports_vec_scatter_store_cached;\n"
3221debfc3dSmrg "};\n"
3231debfc3dSmrg "extern void init_all_optabs (struct target_optabs *);\n"
3241debfc3dSmrg "\n"
3251debfc3dSmrg "extern struct target_optabs default_target_optabs;\n"
3261debfc3dSmrg "extern struct target_optabs *this_fn_optabs;\n"
3271debfc3dSmrg "#if SWITCHABLE_TARGET\n"
3281debfc3dSmrg "extern struct target_optabs *this_target_optabs;\n"
3291debfc3dSmrg "#else\n"
3301debfc3dSmrg "#define this_target_optabs (&default_target_optabs)\n"
3311debfc3dSmrg "#endif\n");
3321debfc3dSmrg
3331debfc3dSmrg fprintf (s_file,
334a2dc1f3fSmrg "#define IN_TARGET_CODE 1\n"
3351debfc3dSmrg "#include \"config.h\"\n"
3361debfc3dSmrg "#include \"system.h\"\n"
3371debfc3dSmrg "#include \"coretypes.h\"\n"
3381debfc3dSmrg "#include \"backend.h\"\n"
3391debfc3dSmrg "#include \"predict.h\"\n"
3401debfc3dSmrg "#include \"tree.h\"\n"
3411debfc3dSmrg "#include \"rtl.h\"\n"
3421debfc3dSmrg "#include \"alias.h\"\n"
3431debfc3dSmrg "#include \"varasm.h\"\n"
3441debfc3dSmrg "#include \"stor-layout.h\"\n"
3451debfc3dSmrg "#include \"calls.h\"\n"
3461debfc3dSmrg "#include \"memmodel.h\"\n"
3471debfc3dSmrg "#include \"tm_p.h\"\n"
3481debfc3dSmrg "#include \"flags.h\"\n"
3491debfc3dSmrg "#include \"insn-config.h\"\n"
3501debfc3dSmrg "#include \"expmed.h\"\n"
3511debfc3dSmrg "#include \"dojump.h\"\n"
3521debfc3dSmrg "#include \"explow.h\"\n"
3531debfc3dSmrg "#include \"emit-rtl.h\"\n"
3541debfc3dSmrg "#include \"stmt.h\"\n"
3551debfc3dSmrg "#include \"expr.h\"\n"
3561debfc3dSmrg "#include \"insn-codes.h\"\n"
3571debfc3dSmrg "#include \"optabs.h\"\n"
3581debfc3dSmrg "\n"
3591debfc3dSmrg "struct optab_pat {\n"
3601debfc3dSmrg " unsigned scode;\n"
3611debfc3dSmrg " enum insn_code icode;\n"
3621debfc3dSmrg "};\n\n");
3631debfc3dSmrg
3641debfc3dSmrg fprintf (s_file,
3651debfc3dSmrg "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
3661debfc3dSmrg for (i = 0; patterns.iterate (i, &p); ++i)
3671debfc3dSmrg fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
3681debfc3dSmrg fprintf (s_file, "};\n\n");
3691debfc3dSmrg
3701debfc3dSmrg fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
3711debfc3dSmrg fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
3721debfc3dSmrg for (i = 0; patterns.iterate (i, &p); ++i)
3731debfc3dSmrg fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
3741debfc3dSmrg fprintf (s_file, "}\n\n");
3751debfc3dSmrg
3761debfc3dSmrg /* Perform a binary search on a pre-encoded optab+mode*2. */
3771debfc3dSmrg /* ??? Perhaps even better to generate a minimal perfect hash.
3781debfc3dSmrg Using gperf directly is awkward since it's so geared to working
3791debfc3dSmrg with strings. Plus we have no visibility into the ordering of
3801debfc3dSmrg the hash entries, which complicates the pat_enable array. */
3811debfc3dSmrg fprintf (s_file,
3821debfc3dSmrg "static int\n"
3831debfc3dSmrg "lookup_handler (unsigned scode)\n"
3841debfc3dSmrg "{\n"
3851debfc3dSmrg " int l = 0, h = ARRAY_SIZE (pats), m;\n"
3861debfc3dSmrg " while (h > l)\n"
3871debfc3dSmrg " {\n"
3881debfc3dSmrg " m = (h + l) / 2;\n"
3891debfc3dSmrg " if (scode == pats[m].scode)\n"
3901debfc3dSmrg " return m;\n"
3911debfc3dSmrg " else if (scode < pats[m].scode)\n"
3921debfc3dSmrg " h = m;\n"
3931debfc3dSmrg " else\n"
3941debfc3dSmrg " l = m + 1;\n"
3951debfc3dSmrg " }\n"
3961debfc3dSmrg " return -1;\n"
3971debfc3dSmrg "}\n\n");
3981debfc3dSmrg
3991debfc3dSmrg fprintf (s_file,
4001debfc3dSmrg "enum insn_code\n"
4011debfc3dSmrg "raw_optab_handler (unsigned scode)\n"
4021debfc3dSmrg "{\n"
4031debfc3dSmrg " int i = lookup_handler (scode);\n"
4041debfc3dSmrg " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
4051debfc3dSmrg " ? pats[i].icode : CODE_FOR_nothing);\n"
4061debfc3dSmrg "}\n\n");
4071debfc3dSmrg
4081debfc3dSmrg fprintf (s_file,
4091debfc3dSmrg "bool\n"
4101debfc3dSmrg "swap_optab_enable (optab op, machine_mode m, bool set)\n"
4111debfc3dSmrg "{\n"
4121debfc3dSmrg " unsigned scode = (op << 16) | m;\n"
4131debfc3dSmrg " int i = lookup_handler (scode);\n"
4141debfc3dSmrg " if (i >= 0)\n"
4151debfc3dSmrg " {\n"
4161debfc3dSmrg " bool ret = this_fn_optabs->pat_enable[i];\n"
4171debfc3dSmrg " this_fn_optabs->pat_enable[i] = set;\n"
4181debfc3dSmrg " return ret;\n"
4191debfc3dSmrg " }\n"
4201debfc3dSmrg " else\n"
4211debfc3dSmrg " {\n"
4221debfc3dSmrg " gcc_assert (!set);\n"
4231debfc3dSmrg " return false;\n"
4241debfc3dSmrg " }\n"
4251debfc3dSmrg "}\n\n");
4261debfc3dSmrg
4271debfc3dSmrg /* C++ (even G++) does not support (non-trivial) designated initializers.
4281debfc3dSmrg To work around that, generate these arrays programatically rather than
4291debfc3dSmrg by our traditional multiple inclusion of def files. */
4301debfc3dSmrg
4311debfc3dSmrg fprintf (s_file,
4321debfc3dSmrg "const struct convert_optab_libcall_d "
4331debfc3dSmrg "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
4341debfc3dSmrg for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
4351debfc3dSmrg fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
4361debfc3dSmrg fprintf (s_file, "};\n\n");
4371debfc3dSmrg
4381debfc3dSmrg fprintf (s_file,
4391debfc3dSmrg "const struct optab_libcall_d "
4401debfc3dSmrg "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
4411debfc3dSmrg for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
4421debfc3dSmrg fprintf (s_file, " { %s, %s, %s },\n",
4431debfc3dSmrg optabs[i].suffix, optabs[i].base, optabs[i].libcall);
4441debfc3dSmrg fprintf (s_file, "};\n\n");
4451debfc3dSmrg
4461debfc3dSmrg fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
4471debfc3dSmrg for (i = 0; i < n; ++i)
4481debfc3dSmrg fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
4491debfc3dSmrg fprintf (s_file, "};\n\n");
4501debfc3dSmrg
4511debfc3dSmrg qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
4521debfc3dSmrg
4531debfc3dSmrg fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
4541debfc3dSmrg for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
4551debfc3dSmrg continue;
4561debfc3dSmrg for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
4571debfc3dSmrg {
4581debfc3dSmrg if (j < n && optabs[j].rcode == i)
4591debfc3dSmrg fprintf (s_file, " %s,\n", optabs[j++].name);
4601debfc3dSmrg else
4611debfc3dSmrg fprintf (s_file, " unknown_optab,\n");
4621debfc3dSmrg }
4631debfc3dSmrg fprintf (s_file, "};\n\n");
4641debfc3dSmrg
4651debfc3dSmrg fprintf (h_file, "#endif\n");
4661debfc3dSmrg return (fclose (h_file) == 0 && fclose (s_file) == 0
4671debfc3dSmrg ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
4681debfc3dSmrg }
469