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
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
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/>. */
22 #include "coretypes.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 *);
41 insn_hasher::hash (rtx x
)
43 return htab_hash_string (XSTR (x
, 0));
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
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. */
67 def_target_insn (const char *name
, const char *prototype
)
69 /* Get an upper-case form of NAME. */
71 char *upper_name
= XALLOCAVEC (char, strlen (name
) + 1);
72 for (i
= 0; name
[i
]; ++i
)
73 upper_name
[i
] = TOUPPER (name
[i
]);
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);
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. */
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
);
99 else if (*p
== ')' || *p
== ',')
101 /* We found the end of a parameter without finding a
103 if (strcmp (prototype
, "(void)") != 0)
105 error ("argument %d of '%s' did not have the expected name",
107 exit (FATAL_EXIT_CODE
);
110 else if (*p
!= '(' && !ISSPACE (*p
))
114 /* See whether we have an implementation of this pattern. */
115 hashval_t hash
= htab_hash_string (name
);
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);
125 /* Try to reuse an existing function that performs the same test. */
127 const char *&entry
= have_funcs
->get_or_insert (test
, &existed
);
131 printf ("\nstatic bool\n");
132 printf ("target_have_%s (void)\n", name
);
135 print_c_condition (test
);
141 printf ("\nstatic rtx_insn *\n");
142 printf ("target_gen_%s %s\n", name
, prototype
);
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
);
154 const char **slot
= stubs
->find_slot (suffix
, INSERT
);
157 *slot
= xstrdup (suffix
);
158 printf ("\nstatic rtx_insn *\n");
159 printf ("invalid_%s ", suffix
);
160 const char *p
= prototype
;
163 if (p
[0] == 'x' && ISDIGIT (p
[1]))
166 strtol (p
+ 1, &endptr
, 10);
170 fputc (*p
++, stdout
);
173 printf (" gcc_unreachable ();\n");
177 printf ("\n#undef TARGET_HAVE_%s\n", upper_name
);
178 printf ("#define TARGET_HAVE_%s ", upper_name
);
180 printf ("hook_bool_void_false\n");
182 printf ("hook_bool_void_true\n");
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
);
189 printf ("invalid_%s\n", suffix
);
191 printf ("target_gen_%s\n", name
);
193 printf ("#undef TARGET_CODE_FOR_%s\n", upper_name
);
194 printf ("#define TARGET_CODE_FOR_%s ", upper_name
);
196 printf ("CODE_FOR_nothing\n");
198 printf ("CODE_FOR_%s\n", name
);
201 /* Record the DEFINE_INSN or DEFINE_EXPAND described by INFO. */
204 add_insn (md_rtx_info
*info
)
207 const char *name
= XSTR (def
, 0);
208 if (name
[0] == 0 || name
[0] == '*')
211 hashval_t hash
= htab_hash_string (name
);
212 rtx
*slot
= insns
->find_slot_with_hash (name
, hash
, INSERT
);
214 error_at (info
->loc
, "duplicate definition of '%s'", name
);
220 main (int argc
, char **argv
)
222 progname
= "gentarget-def";
224 if (!init_rtx_reader_args (argc
, argv
))
225 return (FATAL_EXIT_CODE
);
227 insns
= new hash_table
<insn_hasher
> (31);
228 stubs
= new hash_table
<nofree_string_hash
> (31);
229 have_funcs
= new hash_map
<nofree_string_hash
, const char *>;
232 while (read_md_rtx (&info
))
233 switch (GET_CODE (info
.def
))
244 printf ("/* Generated automatically by the program `gentarget-def'. */\n");
245 printf ("#ifndef GCC_INSN_TARGET_DEF_H\n");
246 printf ("#define GCC_INSN_TARGET_DEF_H\n");
248 /* Output a routine to convert an rtx to an rtx_insn sequence.
249 ??? At some point the gen_* functions themselves should return
251 printf ("\nstatic inline rtx_insn *\n");
252 printf ("insnify (rtx x)\n");
254 printf (" if (!x)\n");
255 printf (" return NULL;\n");
256 printf (" if (rtx_insn *insn = dyn_cast <rtx_insn *> (x))\n");
257 printf (" return insn;\n");
258 printf (" start_sequence ();\n");
259 printf (" emit (x, false);\n");
260 printf (" rtx_insn *res = get_insns ();\n");
261 printf (" end_sequence ();\n");
262 printf (" return res;\n");
265 #define DEF_TARGET_INSN(INSN, ARGS) \
266 def_target_insn (#INSN, #ARGS);
267 #include "target-insns.def"
268 #undef DEF_TARGET_INSN
270 printf ("\n#endif /* GCC_INSN_TARGET_DEF_H */\n");
272 if (have_error
|| ferror (stdout
) || fflush (stdout
) || fclose (stdout
))
273 return FATAL_EXIT_CODE
;
275 return SUCCESS_EXIT_CODE
;