poly_int: loop versioning threshold
[official-gcc.git] / gcc / gencfn-macros.c
blob5b38ac20a4d02d96a3b07f97f4028a474fd99e25
1 /* Generate macros based on the combined_fn enum.
2 Copyright (C) 2015-2017 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 /* Automatically generate code fragments related to combined_fn.
22 The program looks for math built-in functions that have float, double
23 and long double variants, such as {sqrtf, sqrt, sqrtl}, and that may
24 or may not have an associated internal function as well. It also looks
25 for integer built-in functions that have int, long, long long and
26 intmax_t variants, such as {clz, clzl, clzll, clzimax}, and that
27 again may or may not have an associated internal function as well.
29 When run with -c, the generator prints a list of macros such as:
31 CASE_CFN_SQRT
33 for each group of functions described above, with 'case CFN_*'
34 statements for each built-in and internal function in the group.
35 For example, there are both built-in and internal implementations
36 of SQRT, so "CASE_CFN_SQRT:" is equivalent to:
38 case CFN_BUILT_IN_SQRTF:
39 case CFN_BUILT_IN_SQRT:
40 case CFN_BUILT_IN_SQRTL:
41 case CFN_SQRT:
43 The macros for groups with no internal function drop the last line.
45 When run with -o, the generator prints a similar list of
46 define_operator_list directives, for use by match.pd. Each operator
47 list starts with the built-in functions, in order of ascending type width.
48 This is followed by an entry for the internal function, or "null" if there
49 is no internal function for the group. For example:
51 (define_operator_list SQRT
52 BUILT_IN_SQRTF
53 BUILT_IN_SQRT
54 BUILT_IN_SQRTL
55 IFN_SQRT)
57 and:
59 (define_operator_list CABS
60 BUILT_IN_CABSF
61 BUILT_IN_CABS
62 BUILT_IN_CABSL
63 null) */
65 #include "bconfig.h"
66 #include "system.h"
67 #include "coretypes.h"
68 #include "hash-table.h"
69 #include "hash-set.h"
70 #include "errors.h"
72 typedef hash_set <nofree_string_hash> string_set;
74 /* Add all names in null-terminated list NAMES to SET. */
76 static void
77 add_to_set (string_set *set, const char *const *names)
79 for (unsigned int i = 0; names[i]; ++i)
80 set->add (names[i]);
83 /* Return true if *BUILTINS contains BUILT_IN_<NAME><SUFFIX> for all
84 suffixes in null-terminated list SUFFIXES. */
86 static bool
87 is_group (string_set *builtins, const char *name, const char *const *suffixes)
89 for (unsigned int i = 0; suffixes[i]; ++i)
90 if (!builtins->contains (ACONCAT (("BUILT_IN_", name, suffixes[i], NULL))))
91 return false;
92 return true;
95 /* Print a macro for all combined functions related to NAME, with the
96 null-terminated list of suffixes in SUFFIXES. INTERNAL_P says whether
97 CFN_<NAME> also exists. */
99 static void
100 print_case_cfn (const char *name, bool internal_p,
101 const char *const *suffixes, bool floatn_p)
103 const char *floatn = (floatn_p) ? "_FN" : "";
104 printf ("#define CASE_CFN_%s%s", name, floatn);
105 if (internal_p)
106 printf (" \\\n case CFN_%s%s", name, floatn);
107 for (unsigned int i = 0; suffixes[i]; ++i)
108 printf ("%s \\\n case CFN_BUILT_IN_%s%s",
109 internal_p || i > 0 ? ":" : "", name, suffixes[i]);
110 printf ("\n");
113 /* Print an operator list for all combined functions related to NAME,
114 with the null-terminated list of suffixes in SUFFIXES. INTERNAL_P
115 says whether CFN_<NAME> also exists. */
117 static void
118 print_define_operator_list (const char *name, bool internal_p,
119 const char *const *suffixes, bool floatn_p)
121 const char *floatn = (floatn_p) ? "_FN" : "";
122 printf ("(define_operator_list %s%s\n", name, floatn);
123 for (unsigned int i = 0; suffixes[i]; ++i)
124 printf (" BUILT_IN_%s%s\n", name, suffixes[i]);
125 if (internal_p)
126 printf (" IFN_%s)\n", name);
127 else
128 printf (" null)\n");
131 const char *const builtin_names[] = {
132 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
133 #ENUM,
134 #include "builtins.def"
135 NULL
138 const char *const internal_fn_flt_names[] = {
139 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
140 #NAME,
141 #include "internal-fn.def"
142 NULL
145 const char *const internal_fn_int_names[] = {
146 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
147 #NAME,
148 #include "internal-fn.def"
149 NULL
152 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
153 static const char *const fltfn_suffixes[] = { "F16", "F32", "F64", "F128",
154 "F32X", "F64X", "F128X", NULL };
155 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
157 static const char *const *const suffix_lists[] = {
158 flt_suffixes,
159 int_suffixes,
160 NULL
164 main (int argc, char **argv)
166 /* Check arguments. */
167 progname = argv[0];
168 if (argc != 2
169 || argv[1][0] != '-'
170 || !strchr ("co", argv[1][1])
171 || argv[1][2])
172 fatal ("usage: %s [-c|-o] > file", progname);
173 int type = argv[1][1];
175 /* Collect the set of built-in and internal functions. */
176 string_set builtins;
177 string_set internal_fns;
178 add_to_set (&builtins, builtin_names);
179 add_to_set (&internal_fns, internal_fn_flt_names);
180 add_to_set (&internal_fns, internal_fn_int_names);
182 /* Check the functions. */
183 for (unsigned int i = 0; internal_fn_flt_names[i]; ++i)
185 const char *name = internal_fn_flt_names[i];
186 if (!is_group (&builtins, name, flt_suffixes))
187 error ("DEF_INTERNAL_FLT_FN (%s) has no associated built-in"
188 " functions", name);
190 for (unsigned int i = 0; internal_fn_int_names[i]; ++i)
192 const char *name = internal_fn_int_names[i];
193 if (!is_group (&builtins, name, int_suffixes))
194 error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in"
195 " functions", name);
198 /* Go through the built-in functions in declaration order, outputting
199 definitions as appropriate. */
200 for (unsigned int i = 0; builtin_names[i]; ++i)
202 const char *name = builtin_names[i];
203 if (strncmp (name, "BUILT_IN_", 9) == 0)
205 const char *root = name + 9;
206 for (unsigned int j = 0; suffix_lists[j]; ++j)
208 const char *const *const suffix = suffix_lists[j];
210 if (is_group (&builtins, root, suffix))
212 bool internal_p = internal_fns.contains (root);
214 if (type == 'c')
215 print_case_cfn (root, internal_p, suffix, false);
216 else
217 print_define_operator_list (root, internal_p,
218 suffix, false);
220 /* Support the _Float<N> and _Float<N>X math functions if
221 they exist. We put these out as a separate CFN macro,
222 so code can add support or not as needed. */
223 if (suffix == flt_suffixes
224 && is_group (&builtins, root, fltfn_suffixes))
226 if (type == 'c')
227 print_case_cfn (root, false, fltfn_suffixes, true);
228 else
229 print_define_operator_list (root, false, fltfn_suffixes,
230 true);
237 if (fflush (stdout) || fclose (stdout) || have_error)
238 return FATAL_EXIT_CODE;
239 return SUCCESS_EXIT_CODE;