gengenrtl.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /* Generate code to allocate RTL structures.
  2. Copyright (C) 1997-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. struct rtx_definition
  18. {
  19. const char *const enumname, *const name, *const format;
  20. };
  21. /* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
  22. CONST_DOUBLE_FORMAT is because we're not going to be generating
  23. anything for CONST_DOUBLE anyway. */
  24. #define CONST_DOUBLE_FORMAT ""
  25. #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
  26. static const struct rtx_definition defs[] =
  27. {
  28. #include "rtl.def" /* rtl expressions are documented here */
  29. };
  30. #define NUM_RTX_CODE ARRAY_SIZE (defs)
  31. static const char *formats[NUM_RTX_CODE];
  32. /* Decode a format letter into a C type string. */
  33. static const char *
  34. type_from_format (int c)
  35. {
  36. switch (c)
  37. {
  38. case 'i':
  39. return "int ";
  40. case 'w':
  41. return "HOST_WIDE_INT ";
  42. case 's':
  43. return "const char *";
  44. case 'e': case 'u':
  45. return "rtx ";
  46. case 'E':
  47. return "rtvec ";
  48. case 't':
  49. return "tree ";
  50. case 'B':
  51. return "basic_block ";
  52. default:
  53. gcc_unreachable ();
  54. }
  55. }
  56. /* Decode a format letter into the proper accessor function. */
  57. static const char *
  58. accessor_from_format (int c)
  59. {
  60. switch (c)
  61. {
  62. case 'i':
  63. return "XINT";
  64. case 'w':
  65. return "XWINT";
  66. case 's':
  67. return "XSTR";
  68. case 'e': case 'u':
  69. return "XEXP";
  70. case 'E':
  71. return "XVEC";
  72. case 't':
  73. return "XTREE";
  74. case 'B':
  75. return "XBBDEF";
  76. default:
  77. gcc_unreachable ();
  78. }
  79. }
  80. /* Return nonzero if we should ignore FMT, an RTL format, when making
  81. the list of formats we write routines to create. */
  82. static int
  83. special_format (const char *fmt)
  84. {
  85. return (strchr (fmt, '*') != 0
  86. || strchr (fmt, 'V') != 0
  87. || strchr (fmt, 'S') != 0
  88. || strchr (fmt, 'n') != 0);
  89. }
  90. /* Return nonzero if the RTL code given by index IDX is one that we should
  91. generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
  92. is a wrapper in emit-rtl.c). */
  93. static int
  94. special_rtx (int idx)
  95. {
  96. return (strcmp (defs[idx].enumname, "EXPR_LIST") == 0
  97. || strcmp (defs[idx].enumname, "INSN_LIST") == 0
  98. || strcmp (defs[idx].enumname, "INSN") == 0
  99. || strcmp (defs[idx].enumname, "CONST_INT") == 0
  100. || strcmp (defs[idx].enumname, "REG") == 0
  101. || strcmp (defs[idx].enumname, "SUBREG") == 0
  102. || strcmp (defs[idx].enumname, "MEM") == 0
  103. || strcmp (defs[idx].enumname, "PC") == 0
  104. || strcmp (defs[idx].enumname, "CC0") == 0
  105. || strcmp (defs[idx].enumname, "RETURN") == 0
  106. || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0
  107. || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
  108. }
  109. /* Return nonzero if the RTL code given by index IDX is one that we should
  110. generate no macro for at all (because gen_rtx_FOO is never used or
  111. cannot have the obvious interface). */
  112. static int
  113. excluded_rtx (int idx)
  114. {
  115. return (strcmp (defs[idx].enumname, "VAR_LOCATION") == 0
  116. || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
  117. || strcmp (defs[idx].enumname, "CONST_WIDE_INT") == 0
  118. || strcmp (defs[idx].enumname, "CONST_FIXED") == 0);
  119. }
  120. /* Place a list of all format specifiers we use into the array FORMAT. */
  121. static void
  122. find_formats (void)
  123. {
  124. unsigned int i;
  125. for (i = 0; i < NUM_RTX_CODE; i++)
  126. {
  127. const char **f;
  128. if (special_format (defs[i].format))
  129. continue;
  130. for (f = formats; *f; f++)
  131. if (! strcmp (*f, defs[i].format))
  132. break;
  133. if (*f == 0)
  134. *f = defs[i].format;
  135. }
  136. }
  137. /* Generate macros to generate RTL of code IDX using the functions we
  138. write. */
  139. static void
  140. genmacro (int idx)
  141. {
  142. const char *p;
  143. int i;
  144. /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
  145. gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */
  146. if (excluded_rtx (idx))
  147. /* Don't define a macro for this code. */
  148. return;
  149. printf ("#define gen_rtx_%s%s(MODE",
  150. special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
  151. for (p = defs[idx].format, i = 0; *p != 0; p++)
  152. if (*p != '0')
  153. printf (", ARG%d", i++);
  154. printf (") \\\n gen_rtx_fmt_%s (%s, (MODE)",
  155. defs[idx].format, defs[idx].enumname);
  156. for (p = defs[idx].format, i = 0; *p != 0; p++)
  157. if (*p != '0')
  158. printf (", (ARG%d)", i++);
  159. puts (")");
  160. }
  161. /* Generate the code for the function to generate RTL whose
  162. format is FORMAT. */
  163. static void
  164. gendef (const char *format)
  165. {
  166. const char *p;
  167. int i, j;
  168. /* Start by writing the definition of the function name and the types
  169. of the arguments. */
  170. printf ("static inline rtx\ngen_rtx_fmt_%s_stat (RTX_CODE code, machine_mode mode", format);
  171. for (p = format, i = 0; *p != 0; p++)
  172. if (*p != '0')
  173. printf (",\n\t%sarg%d", type_from_format (*p), i++);
  174. puts (" MEM_STAT_DECL)");
  175. /* Now write out the body of the function itself, which allocates
  176. the memory and initializes it. */
  177. puts ("{");
  178. puts (" rtx rt;");
  179. puts (" rt = rtx_alloc_stat (code PASS_MEM_STAT);\n");
  180. puts (" PUT_MODE (rt, mode);");
  181. for (p = format, i = j = 0; *p ; ++p, ++i)
  182. if (*p != '0')
  183. printf (" %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
  184. else
  185. printf (" X0EXP (rt, %d) = NULL_RTX;\n", i);
  186. puts ("\n return rt;\n}\n");
  187. printf ("#define gen_rtx_fmt_%s(c, m", format);
  188. for (p = format, i = 0; *p != 0; p++)
  189. if (*p != '0')
  190. printf (", p%i",i++);
  191. printf (")\\\n gen_rtx_fmt_%s_stat (c, m", format);
  192. for (p = format, i = 0; *p != 0; p++)
  193. if (*p != '0')
  194. printf (", p%i",i++);
  195. printf (" MEM_STAT_INFO)\n\n");
  196. }
  197. /* Generate the documentation header for files we write. */
  198. static void
  199. genlegend (void)
  200. {
  201. puts ("/* Generated automatically by gengenrtl from rtl.def. */\n");
  202. }
  203. /* Generate the text of the header file we make, genrtl.h. */
  204. static void
  205. genheader (void)
  206. {
  207. unsigned int i;
  208. const char **fmt;
  209. puts ("#ifndef GCC_GENRTL_H");
  210. puts ("#define GCC_GENRTL_H\n");
  211. puts ("#include \"statistics.h\"\n");
  212. for (fmt = formats; *fmt; ++fmt)
  213. gendef (*fmt);
  214. putchar ('\n');
  215. for (i = 0; i < NUM_RTX_CODE; i++)
  216. if (! special_format (defs[i].format))
  217. genmacro (i);
  218. puts ("\n#endif /* GCC_GENRTL_H */");
  219. }
  220. /* This is the main program. */
  221. int
  222. main (void)
  223. {
  224. find_formats ();
  225. genlegend ();
  226. genheader ();
  227. if (ferror (stdout) || fflush (stdout) || fclose (stdout))
  228. return FATAL_EXIT_CODE;
  229. return SUCCESS_EXIT_CODE;
  230. }