genopinit.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. /* Generate code to initialize optabs from machine description.
  2. Copyright (C) 1993-2015 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "bconfig.h"
  16. #include "system.h"
  17. #include "coretypes.h"
  18. #include "tm.h"
  19. #include "rtl.h"
  20. #include "errors.h"
  21. #include "gensupport.h"
  22. #define DEF_RTL_EXPR(V, N, X, C) #V,
  23. static const char * const rtx_upname[] = {
  24. #include "rtl.def"
  25. };
  26. #undef DEF_RTL_EXPR
  27. /* The entries in optabs.def are categorized:
  28. C: A "conversion" optab, which uses two modes; has libcall data.
  29. N: A "normal" optab, which uses one mode; has libcall data.
  30. D: A "direct" optab, which uses one mode; does not have libcall data.
  31. V: An "oVerflow" optab. Like N, but does not record its code in
  32. code_to_optab.
  33. CX, NX, VX: An extra pattern entry for a conversion or normal optab.
  34. These patterns may be present in the MD file with names that contain
  35. the mode(s) used and the name of the operation. This array contains
  36. a list of optabs that need to be initialized. Within each name,
  37. $a and $b are used to match a short mode name (the part of the mode
  38. name not including `mode' and converted to lower-case).
  39. $I means that only full integer modes should be considered for the
  40. next mode, and $F means that only float modes should be considered.
  41. $P means that both full and partial integer modes should be considered.
  42. $Q means that only fixed-point modes should be considered.
  43. The pattern may be NULL if the optab exists only for the libcalls
  44. that we plan to attach to it, and there are no named patterns in
  45. the md files. */
  46. #define OPTAB_CL(name, pat, c, b, l) name,
  47. #define OPTAB_CX(name, pat)
  48. #define OPTAB_CD(name, pat) name,
  49. #define OPTAB_NL(name, pat, c, b, s, l) name,
  50. #define OPTAB_NC(name, pat, c) name,
  51. #define OPTAB_NX(name, pat)
  52. #define OPTAB_VL(name, pat, c, b, s, l) name,
  53. #define OPTAB_VC(name, pat, c) name,
  54. #define OPTAB_VX(name, pat)
  55. #define OPTAB_DC(name, pat, c) name,
  56. #define OPTAB_D(name, pat) name,
  57. typedef enum optab_tag {
  58. unknown_optab,
  59. #include "optabs.def"
  60. NUM_OPTABS
  61. } optab;
  62. #undef OPTAB_CL
  63. #undef OPTAB_CX
  64. #undef OPTAB_CD
  65. #undef OPTAB_NL
  66. #undef OPTAB_NC
  67. #undef OPTAB_NX
  68. #undef OPTAB_VL
  69. #undef OPTAB_VC
  70. #undef OPTAB_VX
  71. #undef OPTAB_DC
  72. #undef OPTAB_D
  73. #define NS "NULL"
  74. #define ZS "'\\0'"
  75. #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
  76. #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
  77. #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
  78. #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
  79. #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
  80. #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
  81. #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
  82. #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
  83. #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
  84. #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
  85. #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
  86. typedef struct optab_def_d
  87. {
  88. const char *name;
  89. const char *pattern;
  90. const char *base;
  91. const char *suffix;
  92. const char *libcall;
  93. unsigned int op;
  94. enum rtx_code fcode;
  95. enum rtx_code rcode;
  96. unsigned int kind;
  97. } optab_def;
  98. static optab_def optabs[] = {
  99. { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
  100. #include "optabs.def"
  101. };
  102. #undef OPTAB_CL
  103. #undef OPTAB_CX
  104. #undef OPTAB_CD
  105. #undef OPTAB_NL
  106. #undef OPTAB_NC
  107. #undef OPTAB_NX
  108. #undef OPTAB_VL
  109. #undef OPTAB_VC
  110. #undef OPTAB_VX
  111. #undef OPTAB_DC
  112. #undef OPTAB_D
  113. /* Vector in which to collect insns that match. */
  114. typedef struct pattern_d
  115. {
  116. const char *name;
  117. unsigned int op;
  118. unsigned int m1, m2;
  119. unsigned int sort_num;
  120. } pattern;
  121. static vec<pattern> patterns;
  122. static bool
  123. match_pattern (pattern *p, const char *name, const char *pat)
  124. {
  125. bool force_float = false;
  126. bool force_int = false;
  127. bool force_partial_int = false;
  128. bool force_fixed = false;
  129. if (pat == NULL)
  130. return false;
  131. for (; ; ++pat)
  132. {
  133. if (*pat != '$')
  134. {
  135. if (*pat != *name++)
  136. return false;
  137. if (*pat == '\0')
  138. return true;
  139. continue;
  140. }
  141. switch (*++pat)
  142. {
  143. case 'I':
  144. force_int = 1;
  145. break;
  146. case 'P':
  147. force_partial_int = 1;
  148. break;
  149. case 'F':
  150. force_float = 1;
  151. break;
  152. case 'Q':
  153. force_fixed = 1;
  154. break;
  155. case 'a':
  156. case 'b':
  157. {
  158. int i;
  159. /* This loop will stop at the first prefix match, so
  160. look through the modes in reverse order, in case
  161. there are extra CC modes and CC is a prefix of the
  162. CC modes (as it should be). */
  163. for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
  164. {
  165. const char *p, *q;
  166. for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
  167. if (TOLOWER (*p) != *q)
  168. break;
  169. if (*p == 0
  170. && (! force_int || mode_class[i] == MODE_INT
  171. || mode_class[i] == MODE_VECTOR_INT)
  172. && (! force_partial_int
  173. || mode_class[i] == MODE_INT
  174. || mode_class[i] == MODE_PARTIAL_INT
  175. || mode_class[i] == MODE_VECTOR_INT)
  176. && (! force_float
  177. || mode_class[i] == MODE_FLOAT
  178. || mode_class[i] == MODE_DECIMAL_FLOAT
  179. || mode_class[i] == MODE_COMPLEX_FLOAT
  180. || mode_class[i] == MODE_VECTOR_FLOAT)
  181. && (! force_fixed
  182. || mode_class[i] == MODE_FRACT
  183. || mode_class[i] == MODE_UFRACT
  184. || mode_class[i] == MODE_ACCUM
  185. || mode_class[i] == MODE_UACCUM
  186. || mode_class[i] == MODE_VECTOR_FRACT
  187. || mode_class[i] == MODE_VECTOR_UFRACT
  188. || mode_class[i] == MODE_VECTOR_ACCUM
  189. || mode_class[i] == MODE_VECTOR_UACCUM))
  190. break;
  191. }
  192. if (i < 0)
  193. return false;
  194. name += strlen (GET_MODE_NAME (i));
  195. if (*pat == 'a')
  196. p->m1 = i;
  197. else
  198. p->m2 = i;
  199. force_int = false;
  200. force_partial_int = false;
  201. force_float = false;
  202. force_fixed = false;
  203. }
  204. break;
  205. default:
  206. gcc_unreachable ();
  207. }
  208. }
  209. }
  210. static void
  211. gen_insn (rtx insn)
  212. {
  213. const char *name = XSTR (insn, 0);
  214. pattern p;
  215. unsigned pindex;
  216. /* Don't mention "unnamed" instructions. */
  217. if (*name == 0 || *name == '*')
  218. return;
  219. p.name = name;
  220. /* See if NAME matches one of the patterns we have for the optabs
  221. we know about. */
  222. for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
  223. {
  224. p.m1 = p.m2 = 0;
  225. if (match_pattern (&p, name, optabs[pindex].pattern))
  226. {
  227. p.op = optabs[pindex].op;
  228. p.sort_num = (p.op << 16) | (p.m2 << 8) | p.m1;
  229. patterns.safe_push (p);
  230. return;
  231. }
  232. }
  233. }
  234. static int
  235. pattern_cmp (const void *va, const void *vb)
  236. {
  237. const pattern *a = (const pattern *)va;
  238. const pattern *b = (const pattern *)vb;
  239. return a->sort_num - b->sort_num;
  240. }
  241. static int
  242. optab_kind_cmp (const void *va, const void *vb)
  243. {
  244. const optab_def *a = (const optab_def *)va;
  245. const optab_def *b = (const optab_def *)vb;
  246. int diff = a->kind - b->kind;
  247. if (diff == 0)
  248. diff = a->op - b->op;
  249. return diff;
  250. }
  251. static int
  252. optab_rcode_cmp (const void *va, const void *vb)
  253. {
  254. const optab_def *a = (const optab_def *)va;
  255. const optab_def *b = (const optab_def *)vb;
  256. return a->rcode - b->rcode;
  257. }
  258. static const char *header_file_name = "init-opinit.h";
  259. static const char *source_file_name = "init-opinit.c";
  260. static bool
  261. handle_arg (const char *arg)
  262. {
  263. switch (arg[1])
  264. {
  265. case 'h':
  266. header_file_name = &arg[2];
  267. return true;
  268. case 'c':
  269. source_file_name = &arg[2];
  270. return true;
  271. default:
  272. return false;
  273. }
  274. }
  275. static FILE *
  276. open_outfile (const char *file_name)
  277. {
  278. FILE *f = fopen (file_name, "w");
  279. if (!f)
  280. fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
  281. fprintf (f,
  282. "/* Generated automatically by the program `genopinit'\n"
  283. " from the machine description file `md'. */\n\n");
  284. return f;
  285. }
  286. int
  287. main (int argc, char **argv)
  288. {
  289. FILE *h_file, *s_file;
  290. unsigned int i, j, n, last_kind[5];
  291. pattern *p;
  292. progname = "genopinit";
  293. if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
  294. fatal ("genopinit range assumptions invalid");
  295. if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
  296. return (FATAL_EXIT_CODE);
  297. h_file = open_outfile (header_file_name);
  298. s_file = open_outfile (source_file_name);
  299. /* Read the machine description. */
  300. while (1)
  301. {
  302. int line_no, insn_code_number = 0;
  303. rtx desc = read_md_rtx (&line_no, &insn_code_number);
  304. if (desc == NULL)
  305. break;
  306. if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
  307. gen_insn (desc);
  308. }
  309. /* Sort the collected patterns. */
  310. patterns.qsort (pattern_cmp);
  311. /* Now that we've handled the "extra" patterns, eliminate them from
  312. the optabs array. That way they don't get in the way below. */
  313. n = ARRAY_SIZE (optabs);
  314. for (i = 0; i < n; )
  315. if (optabs[i].base == NULL)
  316. optabs[i] = optabs[--n];
  317. else
  318. ++i;
  319. /* Sort the (real) optabs. Better than forcing the optabs.def file to
  320. remain sorted by kind. We also scrogged any real ordering with the
  321. purging of the X patterns above. */
  322. qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
  323. /* Emit the optab enumeration for the header file. */
  324. fprintf (h_file, "enum optab_tag {\n");
  325. for (i = j = 0; i < n; ++i)
  326. {
  327. optabs[i].op = i;
  328. fprintf (h_file, " %s,\n", optabs[i].name);
  329. if (optabs[i].kind != j)
  330. last_kind[j++] = i - 1;
  331. }
  332. fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
  333. fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
  334. fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
  335. fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
  336. fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
  337. fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
  338. fprintf (h_file, "};\n\n");
  339. fprintf (h_file, "#define NUM_OPTABS %u\n", n);
  340. fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
  341. last_kind[1] - last_kind[0]);
  342. fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
  343. last_kind[3] - last_kind[2]);
  344. fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
  345. (unsigned) patterns.length ());
  346. fprintf (h_file,
  347. "typedef enum optab_tag optab;\n"
  348. "typedef enum optab_tag convert_optab;\n"
  349. "typedef enum optab_tag direct_optab;\n"
  350. "\n"
  351. "struct optab_libcall_d\n"
  352. "{\n"
  353. " char libcall_suffix;\n"
  354. " const char *libcall_basename;\n"
  355. " void (*libcall_gen) (optab, const char *name,\n"
  356. " char suffix, machine_mode);\n"
  357. "};\n"
  358. "\n"
  359. "struct convert_optab_libcall_d\n"
  360. "{\n"
  361. " const char *libcall_basename;\n"
  362. " void (*libcall_gen) (convert_optab, const char *name,\n"
  363. " machine_mode, machine_mode);\n"
  364. "};\n"
  365. "\n"
  366. "/* Given an enum insn_code, access the function to construct\n"
  367. " the body of that kind of insn. */\n"
  368. "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
  369. "\n"
  370. "/* Contains the optab used for each rtx code, and vice-versa. */\n"
  371. "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
  372. "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
  373. "\n"
  374. "static inline optab\n"
  375. "code_to_optab (enum rtx_code code)\n"
  376. "{\n"
  377. " return code_to_optab_[code];\n"
  378. "}\n"
  379. "\n"
  380. "static inline enum rtx_code\n"
  381. "optab_to_code (optab op)\n"
  382. "{\n"
  383. " return optab_to_code_[op];\n"
  384. "}\n"
  385. "\n"
  386. "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
  387. "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
  388. "\n"
  389. "/* Returns the active icode for the given (encoded) optab. */\n"
  390. "extern enum insn_code raw_optab_handler (unsigned);\n"
  391. "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
  392. "\n"
  393. "/* Target-dependent globals. */\n"
  394. "struct target_optabs {\n"
  395. " /* Patterns that are used by optabs that are enabled for this target. */\n"
  396. " bool pat_enable[NUM_OPTAB_PATTERNS];\n"
  397. "};\n"
  398. "extern void init_all_optabs (struct target_optabs *);\n"
  399. "\n"
  400. "extern struct target_optabs default_target_optabs;\n"
  401. "extern struct target_optabs *this_fn_optabs;\n"
  402. "#if SWITCHABLE_TARGET\n"
  403. "extern struct target_optabs *this_target_optabs;\n"
  404. "#else\n"
  405. "#define this_target_optabs (&default_target_optabs)\n"
  406. "#endif\n");
  407. fprintf (s_file,
  408. "#include \"config.h\"\n"
  409. "#include \"system.h\"\n"
  410. "#include \"coretypes.h\"\n"
  411. "#include \"tm.h\"\n"
  412. "#include \"hash-set.h\"\n"
  413. "#include \"machmode.h\"\n"
  414. "#include \"vec.h\"\n"
  415. "#include \"double-int.h\"\n"
  416. "#include \"input.h\"\n"
  417. "#include \"alias.h\"\n"
  418. "#include \"symtab.h\"\n"
  419. "#include \"wide-int.h\"\n"
  420. "#include \"inchash.h\"\n"
  421. "#include \"tree.h\"\n"
  422. "#include \"varasm.h\"\n"
  423. "#include \"stor-layout.h\"\n"
  424. "#include \"calls.h\"\n"
  425. "#include \"rtl.h\"\n"
  426. "#include \"predict.h\"\n"
  427. "#include \"tm_p.h\"\n"
  428. "#include \"flags.h\"\n"
  429. "#include \"insn-config.h\"\n"
  430. "#include \"hashtab.h\"\n"
  431. "#include \"hard-reg-set.h\"\n"
  432. "#include \"function.h\"\n"
  433. "#include \"statistics.h\"\n"
  434. "#include \"real.h\"\n"
  435. "#include \"fixed-value.h\"\n"
  436. "#include \"expmed.h\"\n"
  437. "#include \"dojump.h\"\n"
  438. "#include \"explow.h\"\n"
  439. "#include \"emit-rtl.h\"\n"
  440. "#include \"stmt.h\"\n"
  441. "#include \"expr.h\"\n"
  442. "#include \"insn-codes.h\"\n"
  443. "#include \"optabs.h\"\n"
  444. "\n"
  445. "struct optab_pat {\n"
  446. " unsigned scode;\n"
  447. " enum insn_code icode;\n"
  448. "};\n\n");
  449. fprintf (s_file,
  450. "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
  451. for (i = 0; patterns.iterate (i, &p); ++i)
  452. fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
  453. fprintf (s_file, "};\n\n");
  454. fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
  455. fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
  456. for (i = 0; patterns.iterate (i, &p); ++i)
  457. fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
  458. fprintf (s_file, "}\n\n");
  459. /* Perform a binary search on a pre-encoded optab+mode*2. */
  460. /* ??? Perhaps even better to generate a minimal perfect hash.
  461. Using gperf directly is awkward since it's so geared to working
  462. with strings. Plus we have no visibility into the ordering of
  463. the hash entries, which complicates the pat_enable array. */
  464. fprintf (s_file,
  465. "static int\n"
  466. "lookup_handler (unsigned scode)\n"
  467. "{\n"
  468. " int l = 0, h = ARRAY_SIZE (pats), m;\n"
  469. " while (h > l)\n"
  470. " {\n"
  471. " m = (h + l) / 2;\n"
  472. " if (scode == pats[m].scode)\n"
  473. " return m;\n"
  474. " else if (scode < pats[m].scode)\n"
  475. " h = m;\n"
  476. " else\n"
  477. " l = m + 1;\n"
  478. " }\n"
  479. " return -1;\n"
  480. "}\n\n");
  481. fprintf (s_file,
  482. "enum insn_code\n"
  483. "raw_optab_handler (unsigned scode)\n"
  484. "{\n"
  485. " int i = lookup_handler (scode);\n"
  486. " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
  487. " ? pats[i].icode : CODE_FOR_nothing);\n"
  488. "}\n\n");
  489. fprintf (s_file,
  490. "bool\n"
  491. "swap_optab_enable (optab op, machine_mode m, bool set)\n"
  492. "{\n"
  493. " unsigned scode = (op << 16) | m;\n"
  494. " int i = lookup_handler (scode);\n"
  495. " if (i >= 0)\n"
  496. " {\n"
  497. " bool ret = this_fn_optabs->pat_enable[i];\n"
  498. " this_fn_optabs->pat_enable[i] = set;\n"
  499. " return ret;\n"
  500. " }\n"
  501. " else\n"
  502. " {\n"
  503. " gcc_assert (!set);\n"
  504. " return false;\n"
  505. " }\n"
  506. "}\n\n");
  507. /* C++ (even G++) does not support (non-trivial) designated initializers.
  508. To work around that, generate these arrays programatically rather than
  509. by our traditional multiple inclusion of def files. */
  510. fprintf (s_file,
  511. "const struct convert_optab_libcall_d "
  512. "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
  513. for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
  514. fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
  515. fprintf (s_file, "};\n\n");
  516. fprintf (s_file,
  517. "const struct optab_libcall_d "
  518. "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
  519. for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
  520. fprintf (s_file, " { %s, %s, %s },\n",
  521. optabs[i].suffix, optabs[i].base, optabs[i].libcall);
  522. fprintf (s_file, "};\n\n");
  523. fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
  524. for (i = 0; i < n; ++i)
  525. fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
  526. fprintf (s_file, "};\n\n");
  527. qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
  528. fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
  529. for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
  530. continue;
  531. for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
  532. {
  533. if (j < n && optabs[j].rcode == i)
  534. fprintf (s_file, " %s,\n", optabs[j++].name);
  535. else
  536. fprintf (s_file, " unknown_optab,\n");
  537. }
  538. fprintf (s_file, "};\n\n");
  539. return (fclose (h_file) == 0 && fclose (s_file) == 0
  540. ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
  541. }