Daily bump.
[official-gcc.git] / gcc / gentarget-def.c
blobc1125dde2fecdb163f2e7dc5e31bf77f25fd4e8b
1 /* Generate insn-target-def.h, an automatically-generated part of targetm.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "bconfig.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "rtl.h"
25 #include "errors.h"
26 #include "read-md.h"
27 #include "gensupport.h"
28 #include "hash-table.h"
30 /* This class hashes define_insns and define_expands by name. */
31 struct insn_hasher : nofree_ptr_hash <rtx_def>
33 typedef rtx value_type;
34 typedef const char *compare_type;
36 static inline hashval_t hash (rtx);
37 static inline bool equal (rtx, const char *);
40 hashval_t
41 insn_hasher::hash (rtx x)
43 return htab_hash_string (XSTR (x, 0));
46 bool
47 insn_hasher::equal (rtx x, const char *y)
49 return strcmp (XSTR (x, 0), y) == 0;
52 /* All define_insns and define_expands, hashed by name. */
53 static hash_table <insn_hasher> *insns;
55 /* Records the prototype suffix X for each invalid_X stub that has been
56 generated. */
57 static hash_table <nofree_string_hash> *stubs;
59 /* Records which C conditions have been wrapped in functions, as a mapping
60 from the C condition to the function name. */
61 static hash_map <nofree_string_hash, const char *> *have_funcs;
63 /* Output hook definitions for pattern NAME, which has target-insns.def
64 prototype PROTOTYPE. */
66 static void
67 def_target_insn (const char *name, const char *prototype)
69 /* Get an upper-case form of NAME. */
70 unsigned int i;
71 char *upper_name = XALLOCAVEC (char, strlen (name) + 1);
72 for (i = 0; name[i]; ++i)
73 upper_name[i] = TOUPPER (name[i]);
74 upper_name[i] = 0;
76 /* Check that the prototype is valid and concatenate the types
77 together to get a suffix. */
78 char *suffix = XALLOCAVEC (char, strlen (prototype) + 1);
79 i = 0;
80 unsigned int opno = 0;
81 for (const char *p = prototype; *p; ++p)
82 if (*p == 'x' && ISDIGIT (p[1]))
84 /* This should be a parameter name of the form "x<OPNO>".
85 That doesn't contribute to the suffix, so skip ahead and
86 process the following character. */
87 char *endptr;
88 if ((unsigned int) strtol (p + 1, &endptr, 10) != opno
89 || (*endptr != ',' && *endptr != ')'))
91 error ("invalid prototype for '%s'", name);
92 exit (FATAL_EXIT_CODE);
94 opno += 1;
95 p = endptr;
96 if (*p == ',')
97 suffix[i++] = '_';
99 else if (*p == ')' || *p == ',')
101 /* We found the end of a parameter without finding a
102 parameter name. */
103 if (strcmp (prototype, "(void)") != 0)
105 error ("argument %d of '%s' did not have the expected name",
106 opno, name);
107 exit (FATAL_EXIT_CODE);
110 else if (*p != '(' && !ISSPACE (*p))
111 suffix[i++] = *p;
112 suffix[i] = 0;
114 /* See whether we have an implementation of this pattern. */
115 hashval_t hash = htab_hash_string (name);
116 int truth = 0;
117 const char *have_name = name;
118 if (rtx insn = insns->find_with_hash (name, hash))
120 const char *test = XSTR (insn, 2);
121 truth = maybe_eval_c_test (test);
122 gcc_assert (truth != 0);
123 if (truth < 0)
125 /* Try to reuse an existing function that performs the same test. */
126 bool existed;
127 const char *&entry = have_funcs->get_or_insert (test, &existed);
128 if (!existed)
130 entry = name;
131 printf ("\nstatic bool\n");
132 printf ("target_have_%s (void)\n", name);
133 printf ("{\n");
134 printf (" return ");
135 print_c_condition (test);
136 printf (";\n");
137 printf ("}\n");
139 have_name = entry;
141 printf ("\nstatic rtx_insn *\n");
142 printf ("target_gen_%s %s\n", name, prototype);
143 printf ("{\n");
144 if (truth < 0)
145 printf (" gcc_checking_assert (targetm.have_%s ());\n", name);
146 printf (" return insnify (gen_%s (", name);
147 for (i = 0; i < opno; ++i)
148 printf ("%sx%d", i == 0 ? "" : ", ", i);
149 printf ("));\n");
150 printf ("}\n");
152 else
154 const char **slot = stubs->find_slot (suffix, INSERT);
155 if (!*slot)
157 *slot = xstrdup (suffix);
158 printf ("\nstatic rtx_insn *\n");
159 printf ("invalid_%s ", suffix);
160 const char *p = prototype;
161 while (*p)
163 if (p[0] == 'x' && ISDIGIT (p[1]))
165 char *endptr;
166 strtol (p + 1, &endptr, 10);
167 p = endptr;
169 else
170 fputc (*p++, stdout);
172 printf ("\n{\n");
173 printf (" gcc_unreachable ();\n");
174 printf ("}\n");
177 printf ("\n#undef TARGET_HAVE_%s\n", upper_name);
178 printf ("#define TARGET_HAVE_%s ", upper_name);
179 if (truth == 0)
180 printf ("hook_bool_void_false\n");
181 else if (truth == 1)
182 printf ("hook_bool_void_true\n");
183 else
184 printf ("target_have_%s\n", have_name);
186 printf ("#undef TARGET_GEN_%s\n", upper_name);
187 printf ("#define TARGET_GEN_%s ", upper_name);
188 if (truth == 0)
189 printf ("invalid_%s\n", suffix);
190 else
191 printf ("target_gen_%s\n", name);
195 main (int argc, char **argv)
197 int insn_code_number = 0;
199 progname = "gentarget-def";
201 if (!init_rtx_reader_args (argc, argv))
202 return (FATAL_EXIT_CODE);
204 insns = new hash_table <insn_hasher> (31);
205 stubs = new hash_table <nofree_string_hash> (31);
206 have_funcs = new hash_map <nofree_string_hash, const char *>;
208 while (1)
210 int line_no;
211 rtx desc = read_md_rtx (&line_no, &insn_code_number);
212 if (desc == NULL)
213 break;
214 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
216 const char *name = XSTR (desc, 0);
217 if (name[0] != 0 && name[0] != '*')
219 hashval_t hash = htab_hash_string (name);
220 rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
221 if (*slot)
223 message_with_line (line_no, "duplicate definition of '%s'",
224 name);
225 have_error = 1;
227 else
228 *slot = desc;
233 printf ("/* Generated automatically by the program `gentarget-def'. */\n");
234 printf ("#ifndef GCC_INSN_TARGET_DEF_H\n");
235 printf ("#define GCC_INSN_TARGET_DEF_H\n");
237 /* Output a routine to convert an rtx to an rtx_insn sequence.
238 ??? At some point the gen_* functions themselves should return
239 rtx_insns. */
240 printf ("\nstatic inline rtx_insn *\n");
241 printf ("insnify (rtx x)\n");
242 printf ("{\n");
243 printf (" if (!x)\n");
244 printf (" return NULL;\n");
245 printf (" if (rtx_insn *insn = dyn_cast <rtx_insn *> (x))\n");
246 printf (" return insn;\n");
247 printf (" start_sequence ();\n");
248 printf (" emit (x, false);\n");
249 printf (" rtx_insn *res = get_insns ();\n");
250 printf (" end_sequence ();\n");
251 printf (" return res;\n");
252 printf ("}\n");
254 #define DEF_TARGET_INSN(INSN, ARGS) \
255 def_target_insn (#INSN, #ARGS);
256 #include "target-insns.def"
257 #undef DEF_TARGET_INSN
259 printf ("\n#endif /* GCC_INSN_TARGET_DEF_H */\n");
261 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
262 return FATAL_EXIT_CODE;
264 return SUCCESS_EXIT_CODE;