genemit.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
  1. /* Generate code from machine description to emit insns as rtl.
  2. Copyright (C) 1987-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 "read-md.h"
  22. #include "gensupport.h"
  23. static int insn_code_number;
  24. static int insn_index_number;
  25. /* Data structure for recording the patterns of insns that have CLOBBERs.
  26. We use this to output a function that adds these CLOBBERs to a
  27. previously-allocated PARALLEL expression. */
  28. struct clobber_pat
  29. {
  30. struct clobber_ent *insns;
  31. rtx pattern;
  32. int first_clobber;
  33. struct clobber_pat *next;
  34. int has_hard_reg;
  35. } *clobber_list;
  36. /* Records one insn that uses the clobber list. */
  37. struct clobber_ent
  38. {
  39. int code_number; /* Counts only insns. */
  40. struct clobber_ent *next;
  41. };
  42. static void print_code (RTX_CODE);
  43. static void gen_exp (rtx, enum rtx_code, char *);
  44. static void gen_insn (rtx, int);
  45. static void gen_expand (rtx);
  46. static void gen_split (rtx);
  47. static void output_add_clobbers (void);
  48. static void output_added_clobbers_hard_reg_p (void);
  49. static void gen_rtx_scratch (rtx, enum rtx_code);
  50. static void output_peephole2_scratches (rtx);
  51. static void
  52. print_code (RTX_CODE code)
  53. {
  54. const char *p1;
  55. for (p1 = GET_RTX_NAME (code); *p1; p1++)
  56. putchar (TOUPPER (*p1));
  57. }
  58. static void
  59. gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
  60. {
  61. if (subroutine_type == DEFINE_PEEPHOLE2)
  62. {
  63. printf ("operand%d", XINT (x, 0));
  64. }
  65. else
  66. {
  67. printf ("gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
  68. }
  69. }
  70. /* Print a C expression to construct an RTX just like X,
  71. substituting any operand references appearing within. */
  72. static void
  73. gen_exp (rtx x, enum rtx_code subroutine_type, char *used)
  74. {
  75. RTX_CODE code;
  76. int i;
  77. int len;
  78. const char *fmt;
  79. if (x == 0)
  80. {
  81. printf ("NULL_RTX");
  82. return;
  83. }
  84. code = GET_CODE (x);
  85. switch (code)
  86. {
  87. case MATCH_OPERAND:
  88. case MATCH_DUP:
  89. if (used)
  90. {
  91. if (used[XINT (x, 0)])
  92. {
  93. printf ("copy_rtx (operand%d)", XINT (x, 0));
  94. return;
  95. }
  96. used[XINT (x, 0)] = 1;
  97. }
  98. printf ("operand%d", XINT (x, 0));
  99. return;
  100. case MATCH_OP_DUP:
  101. printf ("gen_rtx_fmt_");
  102. for (i = 0; i < XVECLEN (x, 1); i++)
  103. printf ("e");
  104. printf (" (GET_CODE (operand%d), ", XINT (x, 0));
  105. if (GET_MODE (x) == VOIDmode)
  106. printf ("GET_MODE (operand%d)", XINT (x, 0));
  107. else
  108. printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
  109. for (i = 0; i < XVECLEN (x, 1); i++)
  110. {
  111. printf (",\n\t\t");
  112. gen_exp (XVECEXP (x, 1, i), subroutine_type, used);
  113. }
  114. printf (")");
  115. return;
  116. case MATCH_OPERATOR:
  117. printf ("gen_rtx_fmt_");
  118. for (i = 0; i < XVECLEN (x, 2); i++)
  119. printf ("e");
  120. printf (" (GET_CODE (operand%d)", XINT (x, 0));
  121. printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
  122. for (i = 0; i < XVECLEN (x, 2); i++)
  123. {
  124. printf (",\n\t\t");
  125. gen_exp (XVECEXP (x, 2, i), subroutine_type, used);
  126. }
  127. printf (")");
  128. return;
  129. case MATCH_PARALLEL:
  130. case MATCH_PAR_DUP:
  131. printf ("operand%d", XINT (x, 0));
  132. return;
  133. case MATCH_SCRATCH:
  134. gen_rtx_scratch (x, subroutine_type);
  135. return;
  136. case PC:
  137. printf ("pc_rtx");
  138. return;
  139. case RETURN:
  140. printf ("ret_rtx");
  141. return;
  142. case SIMPLE_RETURN:
  143. printf ("simple_return_rtx");
  144. return;
  145. case CLOBBER:
  146. if (REG_P (XEXP (x, 0)))
  147. {
  148. printf ("gen_hard_reg_clobber (%smode, %i)", GET_MODE_NAME (GET_MODE (XEXP (x, 0))),
  149. REGNO (XEXP (x, 0)));
  150. return;
  151. }
  152. break;
  153. case CC0:
  154. printf ("cc0_rtx");
  155. return;
  156. case CONST_INT:
  157. if (INTVAL (x) == 0)
  158. printf ("const0_rtx");
  159. else if (INTVAL (x) == 1)
  160. printf ("const1_rtx");
  161. else if (INTVAL (x) == -1)
  162. printf ("constm1_rtx");
  163. else if (-MAX_SAVED_CONST_INT <= INTVAL (x)
  164. && INTVAL (x) <= MAX_SAVED_CONST_INT)
  165. printf ("const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
  166. (int) INTVAL (x));
  167. else if (INTVAL (x) == STORE_FLAG_VALUE)
  168. printf ("const_true_rtx");
  169. else
  170. {
  171. printf ("GEN_INT (");
  172. printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
  173. printf (")");
  174. }
  175. return;
  176. case CONST_DOUBLE:
  177. case CONST_FIXED:
  178. case CONST_WIDE_INT:
  179. /* These shouldn't be written in MD files. Instead, the appropriate
  180. routines in varasm.c should be called. */
  181. gcc_unreachable ();
  182. default:
  183. break;
  184. }
  185. printf ("gen_rtx_");
  186. print_code (code);
  187. printf (" (%smode", GET_MODE_NAME (GET_MODE (x)));
  188. fmt = GET_RTX_FORMAT (code);
  189. len = GET_RTX_LENGTH (code);
  190. for (i = 0; i < len; i++)
  191. {
  192. if (fmt[i] == '0')
  193. break;
  194. printf (",\n\t");
  195. switch (fmt[i])
  196. {
  197. case 'e': case 'u':
  198. gen_exp (XEXP (x, i), subroutine_type, used);
  199. break;
  200. case 'i':
  201. printf ("%u", XINT (x, i));
  202. break;
  203. case 's':
  204. printf ("\"%s\"", XSTR (x, i));
  205. break;
  206. case 'E':
  207. {
  208. int j;
  209. printf ("gen_rtvec (%d", XVECLEN (x, i));
  210. for (j = 0; j < XVECLEN (x, i); j++)
  211. {
  212. printf (",\n\t\t");
  213. gen_exp (XVECEXP (x, i, j), subroutine_type, used);
  214. }
  215. printf (")");
  216. break;
  217. }
  218. default:
  219. gcc_unreachable ();
  220. }
  221. }
  222. printf (")");
  223. }
  224. /* Generate the `gen_...' function for a DEFINE_INSN. */
  225. static void
  226. gen_insn (rtx insn, int lineno)
  227. {
  228. struct pattern_stats stats;
  229. int i;
  230. /* See if the pattern for this insn ends with a group of CLOBBERs of (hard)
  231. registers or MATCH_SCRATCHes. If so, store away the information for
  232. later. */
  233. if (XVEC (insn, 1))
  234. {
  235. int has_hard_reg = 0;
  236. for (i = XVECLEN (insn, 1) - 1; i > 0; i--)
  237. {
  238. if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER)
  239. break;
  240. if (REG_P (XEXP (XVECEXP (insn, 1, i), 0)))
  241. has_hard_reg = 1;
  242. else if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH)
  243. break;
  244. }
  245. if (i != XVECLEN (insn, 1) - 1)
  246. {
  247. struct clobber_pat *p;
  248. struct clobber_ent *link = XNEW (struct clobber_ent);
  249. int j;
  250. link->code_number = insn_code_number;
  251. /* See if any previous CLOBBER_LIST entry is the same as this
  252. one. */
  253. for (p = clobber_list; p; p = p->next)
  254. {
  255. if (p->first_clobber != i + 1
  256. || XVECLEN (p->pattern, 1) != XVECLEN (insn, 1))
  257. continue;
  258. for (j = i + 1; j < XVECLEN (insn, 1); j++)
  259. {
  260. rtx old_rtx = XEXP (XVECEXP (p->pattern, 1, j), 0);
  261. rtx new_rtx = XEXP (XVECEXP (insn, 1, j), 0);
  262. /* OLD and NEW_INSN are the same if both are to be a SCRATCH
  263. of the same mode,
  264. or if both are registers of the same mode and number. */
  265. if (! (GET_MODE (old_rtx) == GET_MODE (new_rtx)
  266. && ((GET_CODE (old_rtx) == MATCH_SCRATCH
  267. && GET_CODE (new_rtx) == MATCH_SCRATCH)
  268. || (REG_P (old_rtx) && REG_P (new_rtx)
  269. && REGNO (old_rtx) == REGNO (new_rtx)))))
  270. break;
  271. }
  272. if (j == XVECLEN (insn, 1))
  273. break;
  274. }
  275. if (p == 0)
  276. {
  277. p = XNEW (struct clobber_pat);
  278. p->insns = 0;
  279. p->pattern = insn;
  280. p->first_clobber = i + 1;
  281. p->next = clobber_list;
  282. p->has_hard_reg = has_hard_reg;
  283. clobber_list = p;
  284. }
  285. link->next = p->insns;
  286. p->insns = link;
  287. }
  288. }
  289. /* Don't mention instructions whose names are the null string
  290. or begin with '*'. They are in the machine description just
  291. to be recognized. */
  292. if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
  293. return;
  294. printf ("/* %s:%d */\n", read_md_filename, lineno);
  295. /* Find out how many operands this function has. */
  296. get_pattern_stats (&stats, XVEC (insn, 1));
  297. if (stats.max_dup_opno > stats.max_opno)
  298. fatal ("match_dup operand number has no match_operand");
  299. /* Output the function name and argument declarations. */
  300. printf ("rtx\ngen_%s (", XSTR (insn, 0));
  301. if (stats.num_generator_args)
  302. for (i = 0; i < stats.num_generator_args; i++)
  303. if (i)
  304. printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
  305. else
  306. printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
  307. else
  308. printf ("void");
  309. printf (")\n");
  310. printf ("{\n");
  311. /* Output code to construct and return the rtl for the instruction body. */
  312. if (XVECLEN (insn, 1) == 1)
  313. {
  314. printf (" return ");
  315. gen_exp (XVECEXP (insn, 1, 0), DEFINE_INSN, NULL);
  316. printf (";\n}\n\n");
  317. }
  318. else
  319. {
  320. char *used = XCNEWVEC (char, stats.num_generator_args);
  321. printf (" return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (%d",
  322. XVECLEN (insn, 1));
  323. for (i = 0; i < XVECLEN (insn, 1); i++)
  324. {
  325. printf (",\n\t\t");
  326. gen_exp (XVECEXP (insn, 1, i), DEFINE_INSN, used);
  327. }
  328. printf ("));\n}\n\n");
  329. XDELETEVEC (used);
  330. }
  331. }
  332. /* Generate the `gen_...' function for a DEFINE_EXPAND. */
  333. static void
  334. gen_expand (rtx expand)
  335. {
  336. struct pattern_stats stats;
  337. int i;
  338. char *used;
  339. if (strlen (XSTR (expand, 0)) == 0)
  340. fatal ("define_expand lacks a name");
  341. if (XVEC (expand, 1) == 0)
  342. fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
  343. /* Find out how many operands this function has. */
  344. get_pattern_stats (&stats, XVEC (expand, 1));
  345. /* Output the function name and argument declarations. */
  346. printf ("rtx\ngen_%s (", XSTR (expand, 0));
  347. if (stats.num_generator_args)
  348. for (i = 0; i < stats.num_generator_args; i++)
  349. if (i)
  350. printf (",\n\trtx operand%d", i);
  351. else
  352. printf ("rtx operand%d", i);
  353. else
  354. printf ("void");
  355. printf (")\n");
  356. printf ("{\n");
  357. /* If we don't have any C code to write, only one insn is being written,
  358. and no MATCH_DUPs are present, we can just return the desired insn
  359. like we do for a DEFINE_INSN. This saves memory. */
  360. if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0')
  361. && stats.max_opno >= stats.max_dup_opno
  362. && XVECLEN (expand, 1) == 1)
  363. {
  364. printf (" return ");
  365. gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL);
  366. printf (";\n}\n\n");
  367. return;
  368. }
  369. /* For each operand referred to only with MATCH_DUPs,
  370. make a local variable. */
  371. for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++)
  372. printf (" rtx operand%d;\n", i);
  373. for (; i <= stats.max_scratch_opno; i++)
  374. printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
  375. printf (" rtx _val = 0;\n");
  376. printf (" start_sequence ();\n");
  377. /* The fourth operand of DEFINE_EXPAND is some code to be executed
  378. before the actual construction.
  379. This code expects to refer to `operands'
  380. just as the output-code in a DEFINE_INSN does,
  381. but here `operands' is an automatic array.
  382. So copy the operand values there before executing it. */
  383. if (XSTR (expand, 3) && *XSTR (expand, 3))
  384. {
  385. printf (" {\n");
  386. if (stats.num_operand_vars > 0)
  387. printf (" rtx operands[%d];\n", stats.num_operand_vars);
  388. /* Output code to copy the arguments into `operands'. */
  389. for (i = 0; i < stats.num_generator_args; i++)
  390. printf (" operands[%d] = operand%d;\n", i, i);
  391. /* Output the special code to be executed before the sequence
  392. is generated. */
  393. print_md_ptr_loc (XSTR (expand, 3));
  394. printf ("%s\n", XSTR (expand, 3));
  395. /* Output code to copy the arguments back out of `operands'
  396. (unless we aren't going to use them at all). */
  397. if (XVEC (expand, 1) != 0)
  398. {
  399. for (i = 0; i < stats.num_operand_vars; i++)
  400. {
  401. printf (" operand%d = operands[%d];\n", i, i);
  402. printf (" (void) operand%d;\n", i);
  403. }
  404. }
  405. printf (" }\n");
  406. }
  407. /* Output code to construct the rtl for the instruction bodies.
  408. Use emit_insn to add them to the sequence being accumulated.
  409. But don't do this if the user's code has set `no_more' nonzero. */
  410. used = XCNEWVEC (char, stats.num_operand_vars);
  411. for (i = 0; i < XVECLEN (expand, 1); i++)
  412. {
  413. rtx next = XVECEXP (expand, 1, i);
  414. if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
  415. || (GET_CODE (next) == PARALLEL
  416. && ((GET_CODE (XVECEXP (next, 0, 0)) == SET
  417. && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
  418. || ANY_RETURN_P (XVECEXP (next, 0, 0))))
  419. || ANY_RETURN_P (next))
  420. printf (" emit_jump_insn (");
  421. else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
  422. || GET_CODE (next) == CALL
  423. || (GET_CODE (next) == PARALLEL
  424. && GET_CODE (XVECEXP (next, 0, 0)) == SET
  425. && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)
  426. || (GET_CODE (next) == PARALLEL
  427. && GET_CODE (XVECEXP (next, 0, 0)) == CALL))
  428. printf (" emit_call_insn (");
  429. else if (LABEL_P (next))
  430. printf (" emit_label (");
  431. else if (GET_CODE (next) == MATCH_OPERAND
  432. || GET_CODE (next) == MATCH_DUP
  433. || GET_CODE (next) == MATCH_OPERATOR
  434. || GET_CODE (next) == MATCH_OP_DUP
  435. || GET_CODE (next) == MATCH_PARALLEL
  436. || GET_CODE (next) == MATCH_PAR_DUP
  437. || GET_CODE (next) == PARALLEL)
  438. printf (" emit (");
  439. else
  440. printf (" emit_insn (");
  441. gen_exp (next, DEFINE_EXPAND, used);
  442. printf (");\n");
  443. if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
  444. && GET_CODE (SET_SRC (next)) == LABEL_REF)
  445. printf (" emit_barrier ();");
  446. }
  447. XDELETEVEC (used);
  448. /* Call `get_insns' to extract the list of all the
  449. insns emitted within this gen_... function. */
  450. printf (" _val = get_insns ();\n");
  451. printf (" end_sequence ();\n");
  452. printf (" return _val;\n}\n\n");
  453. }
  454. /* Like gen_expand, but generates insns resulting from splitting SPLIT. */
  455. static void
  456. gen_split (rtx split)
  457. {
  458. struct pattern_stats stats;
  459. int i;
  460. const char *const name =
  461. ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split");
  462. const char *unused;
  463. char *used;
  464. if (XVEC (split, 0) == 0)
  465. fatal ("define_%s (definition %d) lacks a pattern", name,
  466. insn_index_number);
  467. else if (XVEC (split, 2) == 0)
  468. fatal ("define_%s (definition %d) lacks a replacement pattern", name,
  469. insn_index_number);
  470. /* Find out how many operands this function has. */
  471. get_pattern_stats (&stats, XVEC (split, 2));
  472. unused = (stats.num_operand_vars == 0 ? " ATTRIBUTE_UNUSED" : "");
  473. used = XCNEWVEC (char, stats.num_operand_vars);
  474. /* Output the prototype, function name and argument declarations. */
  475. if (GET_CODE (split) == DEFINE_PEEPHOLE2)
  476. {
  477. printf ("extern rtx gen_%s_%d (rtx_insn *, rtx *);\n",
  478. name, insn_code_number);
  479. printf ("rtx\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
  480. name, insn_code_number, unused);
  481. }
  482. else
  483. {
  484. printf ("extern rtx gen_split_%d (rtx_insn *, rtx *);\n", insn_code_number);
  485. printf ("rtx\ngen_split_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
  486. insn_code_number, unused);
  487. }
  488. printf ("{\n");
  489. /* Declare all local variables. */
  490. for (i = 0; i < stats.num_operand_vars; i++)
  491. printf (" rtx operand%d;\n", i);
  492. printf (" rtx _val = 0;\n");
  493. if (GET_CODE (split) == DEFINE_PEEPHOLE2)
  494. output_peephole2_scratches (split);
  495. printf (" if (dump_file)\n");
  496. printf (" fprintf (dump_file, \"Splitting with gen_%s_%d\\n\");\n",
  497. name, insn_code_number);
  498. printf (" start_sequence ();\n");
  499. /* The fourth operand of DEFINE_SPLIT is some code to be executed
  500. before the actual construction. */
  501. if (XSTR (split, 3))
  502. {
  503. print_md_ptr_loc (XSTR (split, 3));
  504. printf ("%s\n", XSTR (split, 3));
  505. }
  506. /* Output code to copy the arguments back out of `operands' */
  507. for (i = 0; i < stats.num_operand_vars; i++)
  508. {
  509. printf (" operand%d = operands[%d];\n", i, i);
  510. printf (" (void) operand%d;\n", i);
  511. }
  512. /* Output code to construct the rtl for the instruction bodies.
  513. Use emit_insn to add them to the sequence being accumulated.
  514. But don't do this if the user's code has set `no_more' nonzero. */
  515. for (i = 0; i < XVECLEN (split, 2); i++)
  516. {
  517. rtx next = XVECEXP (split, 2, i);
  518. if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
  519. || (GET_CODE (next) == PARALLEL
  520. && GET_CODE (XVECEXP (next, 0, 0)) == SET
  521. && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
  522. || ANY_RETURN_P (next))
  523. printf (" emit_jump_insn (");
  524. else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
  525. || GET_CODE (next) == CALL
  526. || (GET_CODE (next) == PARALLEL
  527. && GET_CODE (XVECEXP (next, 0, 0)) == SET
  528. && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)
  529. || (GET_CODE (next) == PARALLEL
  530. && GET_CODE (XVECEXP (next, 0, 0)) == CALL))
  531. printf (" emit_call_insn (");
  532. else if (LABEL_P (next))
  533. printf (" emit_label (");
  534. else if (GET_CODE (next) == MATCH_OPERAND
  535. || GET_CODE (next) == MATCH_OPERATOR
  536. || GET_CODE (next) == MATCH_PARALLEL
  537. || GET_CODE (next) == MATCH_OP_DUP
  538. || GET_CODE (next) == MATCH_DUP
  539. || GET_CODE (next) == PARALLEL)
  540. printf (" emit (");
  541. else
  542. printf (" emit_insn (");
  543. gen_exp (next, GET_CODE (split), used);
  544. printf (");\n");
  545. if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
  546. && GET_CODE (SET_SRC (next)) == LABEL_REF)
  547. printf (" emit_barrier ();");
  548. }
  549. /* Call `get_insns' to make a list of all the
  550. insns emitted within this gen_... function. */
  551. printf (" _val = get_insns ();\n");
  552. printf (" end_sequence ();\n");
  553. printf (" return _val;\n}\n\n");
  554. free (used);
  555. }
  556. /* Write a function, `add_clobbers', that is given a PARALLEL of sufficient
  557. size for the insn and an INSN_CODE, and inserts the required CLOBBERs at
  558. the end of the vector. */
  559. static void
  560. output_add_clobbers (void)
  561. {
  562. struct clobber_pat *clobber;
  563. struct clobber_ent *ent;
  564. int i;
  565. printf ("\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
  566. printf ("{\n");
  567. printf (" switch (insn_code_number)\n");
  568. printf (" {\n");
  569. for (clobber = clobber_list; clobber; clobber = clobber->next)
  570. {
  571. for (ent = clobber->insns; ent; ent = ent->next)
  572. printf (" case %d:\n", ent->code_number);
  573. for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)
  574. {
  575. printf (" XVECEXP (pattern, 0, %d) = ", i);
  576. gen_exp (XVECEXP (clobber->pattern, 1, i),
  577. GET_CODE (clobber->pattern), NULL);
  578. printf (";\n");
  579. }
  580. printf (" break;\n\n");
  581. }
  582. printf (" default:\n");
  583. printf (" gcc_unreachable ();\n");
  584. printf (" }\n");
  585. printf ("}\n");
  586. }
  587. /* Write a function, `added_clobbers_hard_reg_p' that is given an insn_code
  588. number that will have clobbers added (as indicated by `recog') and returns
  589. 1 if those include a clobber of a hard reg or 0 if all of them just clobber
  590. SCRATCH. */
  591. static void
  592. output_added_clobbers_hard_reg_p (void)
  593. {
  594. struct clobber_pat *clobber;
  595. struct clobber_ent *ent;
  596. int clobber_p, used;
  597. printf ("\n\nint\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
  598. printf ("{\n");
  599. printf (" switch (insn_code_number)\n");
  600. printf (" {\n");
  601. for (clobber_p = 0; clobber_p <= 1; clobber_p++)
  602. {
  603. used = 0;
  604. for (clobber = clobber_list; clobber; clobber = clobber->next)
  605. if (clobber->has_hard_reg == clobber_p)
  606. for (ent = clobber->insns; ent; ent = ent->next)
  607. {
  608. printf (" case %d:\n", ent->code_number);
  609. used++;
  610. }
  611. if (used)
  612. printf (" return %d;\n\n", clobber_p);
  613. }
  614. printf (" default:\n");
  615. printf (" gcc_unreachable ();\n");
  616. printf (" }\n");
  617. printf ("}\n");
  618. }
  619. /* Generate code to invoke find_free_register () as needed for the
  620. scratch registers used by the peephole2 pattern in SPLIT. */
  621. static void
  622. output_peephole2_scratches (rtx split)
  623. {
  624. int i;
  625. int insn_nr = 0;
  626. bool first = true;
  627. for (i = 0; i < XVECLEN (split, 0); i++)
  628. {
  629. rtx elt = XVECEXP (split, 0, i);
  630. if (GET_CODE (elt) == MATCH_SCRATCH)
  631. {
  632. int last_insn_nr = insn_nr;
  633. int cur_insn_nr = insn_nr;
  634. int j;
  635. for (j = i + 1; j < XVECLEN (split, 0); j++)
  636. if (GET_CODE (XVECEXP (split, 0, j)) == MATCH_DUP)
  637. {
  638. if (XINT (XVECEXP (split, 0, j), 0) == XINT (elt, 0))
  639. last_insn_nr = cur_insn_nr;
  640. }
  641. else if (GET_CODE (XVECEXP (split, 0, j)) != MATCH_SCRATCH)
  642. cur_insn_nr++;
  643. if (first)
  644. {
  645. printf (" HARD_REG_SET _regs_allocated;\n");
  646. printf (" CLEAR_HARD_REG_SET (_regs_allocated);\n");
  647. first = false;
  648. }
  649. printf (" if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
  650. return NULL;\n",
  651. XINT (elt, 0),
  652. insn_nr, last_insn_nr,
  653. XSTR (elt, 1),
  654. GET_MODE_NAME (GET_MODE (elt)));
  655. }
  656. else if (GET_CODE (elt) != MATCH_DUP)
  657. insn_nr++;
  658. }
  659. }
  660. int
  661. main (int argc, char **argv)
  662. {
  663. rtx desc;
  664. progname = "genemit";
  665. if (!init_rtx_reader_args (argc, argv))
  666. return (FATAL_EXIT_CODE);
  667. /* Assign sequential codes to all entries in the machine description
  668. in parallel with the tables in insn-output.c. */
  669. insn_code_number = 0;
  670. insn_index_number = 0;
  671. printf ("/* Generated automatically by the program `genemit'\n\
  672. from the machine description file `md'. */\n\n");
  673. printf ("#include \"config.h\"\n");
  674. printf ("#include \"system.h\"\n");
  675. printf ("#include \"coretypes.h\"\n");
  676. printf ("#include \"tm.h\"\n");
  677. printf ("#include \"hash-set.h\"\n");
  678. printf ("#include \"machmode.h\"\n");
  679. printf ("#include \"vec.h\"\n");
  680. printf ("#include \"double-int.h\"\n");
  681. printf ("#include \"input.h\"\n");
  682. printf ("#include \"alias.h\"\n");
  683. printf ("#include \"symtab.h\"\n");
  684. printf ("#include \"wide-int.h\"\n");
  685. printf ("#include \"inchash.h\"\n");
  686. printf ("#include \"tree.h\"\n");
  687. printf ("#include \"varasm.h\"\n");
  688. printf ("#include \"stor-layout.h\"\n");
  689. printf ("#include \"calls.h\"\n");
  690. printf ("#include \"rtl.h\"\n");
  691. printf ("#include \"tm_p.h\"\n");
  692. printf ("#include \"hashtab.h\"\n");
  693. printf ("#include \"hard-reg-set.h\"\n");
  694. printf ("#include \"function.h\"\n");
  695. printf ("#include \"flags.h\"\n");
  696. printf ("#include \"statistics.h\"\n");
  697. printf ("#include \"real.h\"\n");
  698. printf ("#include \"fixed-value.h\"\n");
  699. printf ("#include \"insn-config.h\"\n");
  700. printf ("#include \"expmed.h\"\n");
  701. printf ("#include \"dojump.h\"\n");
  702. printf ("#include \"explow.h\"\n");
  703. printf ("#include \"emit-rtl.h\"\n");
  704. printf ("#include \"stmt.h\"\n");
  705. printf ("#include \"expr.h\"\n");
  706. printf ("#include \"insn-codes.h\"\n");
  707. printf ("#include \"optabs.h\"\n");
  708. printf ("#include \"dfp.h\"\n");
  709. printf ("#include \"output.h\"\n");
  710. printf ("#include \"recog.h\"\n");
  711. printf ("#include \"predict.h\"\n");
  712. printf ("#include \"basic-block.h\"\n");
  713. printf ("#include \"resource.h\"\n");
  714. printf ("#include \"reload.h\"\n");
  715. printf ("#include \"diagnostic-core.h\"\n");
  716. printf ("#include \"regs.h\"\n");
  717. printf ("#include \"tm-constrs.h\"\n");
  718. printf ("#include \"ggc.h\"\n");
  719. printf ("#include \"basic-block.h\"\n");
  720. printf ("#include \"dumpfile.h\"\n");
  721. printf ("#include \"target.h\"\n\n");
  722. printf ("#define FAIL return (end_sequence (), _val)\n");
  723. printf ("#define DONE return (_val = get_insns (), end_sequence (), _val)\n\n");
  724. /* Read the machine description. */
  725. while (1)
  726. {
  727. int line_no;
  728. desc = read_md_rtx (&line_no, &insn_code_number);
  729. if (desc == NULL)
  730. break;
  731. switch (GET_CODE (desc))
  732. {
  733. case DEFINE_INSN:
  734. gen_insn (desc, line_no);
  735. break;
  736. case DEFINE_EXPAND:
  737. printf ("/* %s:%d */\n", read_md_filename, line_no);
  738. gen_expand (desc);
  739. break;
  740. case DEFINE_SPLIT:
  741. printf ("/* %s:%d */\n", read_md_filename, line_no);
  742. gen_split (desc);
  743. break;
  744. case DEFINE_PEEPHOLE2:
  745. printf ("/* %s:%d */\n", read_md_filename, line_no);
  746. gen_split (desc);
  747. break;
  748. default:
  749. break;
  750. }
  751. ++insn_index_number;
  752. }
  753. /* Write out the routines to add CLOBBERs to a pattern and say whether they
  754. clobber a hard reg. */
  755. output_add_clobbers ();
  756. output_added_clobbers_hard_reg_p ();
  757. fflush (stdout);
  758. return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
  759. }