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