gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / gencfn-macros.c
1 /* Generate macros based on the combined_fn enum.
2    Copyright (C) 2015-2018 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>.  */
19
20 /* Automatically generate code fragments related to combined_fn.
21
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.
28
29    When run with -c, the generator prints a list of macros such as:
30
31       CASE_CFN_SQRT
32
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:
37
38       case CFN_BUILT_IN_SQRTF:
39       case CFN_BUILT_IN_SQRT:
40       case CFN_BUILT_IN_SQRTL:
41       case CFN_SQRT:
42
43    The macros for groups with no internal function drop the last line.
44
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:
50
51      (define_operator_list SQRT
52          BUILT_IN_SQRTF
53          BUILT_IN_SQRT
54          BUILT_IN_SQRTL
55          IFN_SQRT)
56
57    and:
58
59      (define_operator_list CABS
60          BUILT_IN_CABSF
61          BUILT_IN_CABS
62          BUILT_IN_CABSL
63          null)  */
64
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"
71
72 typedef hash_set <nofree_string_hash> string_set;
73
74 /* Add all names in null-terminated list NAMES to SET.  */
75
76 static void
77 add_to_set (string_set *set, const char *const *names)
78 {
79   for (unsigned int i = 0; names[i]; ++i)
80     set->add (names[i]);
81 }
82
83 /* Return true if *BUILTINS contains BUILT_IN_<NAME><SUFFIX> for all
84    suffixes in null-terminated list SUFFIXES.  */
85
86 static bool
87 is_group (string_set *builtins, const char *name, const char *const *suffixes)
88 {
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;
93 }
94
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.  FLOATN_P is a suffix to the operator name, blank
98    for normal operators, "_FN" for _Float<N>/_Float<N>X operators only, and
99    "_ALL" for both the traditional operators and the _Float<N>/_Float<N>X
100    operators.  */
101
102 static void
103 print_case_cfn (const char *name, bool internal_p,
104                 const char *const *suffixes, const char *floatn)
105 {
106   printf ("#define CASE_CFN_%s%s", name, floatn);
107   if (internal_p)
108     printf (" \\\n  case CFN_%s%s", name, floatn);
109   for (unsigned int i = 0; suffixes[i]; ++i)
110     printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
111             internal_p || i > 0 ? ":" : "", name, suffixes[i]);
112   printf ("\n");
113 }
114
115 /* Print an operator list for all combined functions related to NAME, with the
116    null-terminated list of suffixes in SUFFIXES.  INTERNAL_P says whether
117    CFN_<NAME> also exists.  FLOATN_P is a suffix to the operator name, blank
118    for normal operators, "_FN" for _Float<N>/_Float<N>X operators only, and
119    "_ALL" for both the traditional operators and the _Float<N>/_Float<N>X
120    operators.  */
121
122 static void
123 print_define_operator_list (const char *name, bool internal_p,
124                             const char *const *suffixes,
125                             const char *floatn)
126 {
127   printf ("(define_operator_list %s%s\n", name, floatn);
128   for (unsigned int i = 0; suffixes[i]; ++i)
129     printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
130   if (internal_p)
131     printf ("    IFN_%s)\n", name);
132   else
133     printf ("    null)\n");
134 }
135
136 const char *const builtin_names[] = {
137 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
138   #ENUM,
139 #include "builtins.def"
140   NULL
141 };
142
143 const char *const internal_fn_flt_names[] = {
144 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
145   #NAME,
146 #include "internal-fn.def"
147   NULL
148 };
149
150 const char *const internal_fn_int_names[] = {
151 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
152   #NAME,
153 #include "internal-fn.def"
154   NULL
155 };
156
157 static const char *const flt_suffixes[] = { "F", "", "L", NULL };
158 static const char *const fltfn_suffixes[] = { "F16", "F32", "F64", "F128",
159                                               "F32X", "F64X", "F128X", NULL };
160 static const char *const fltall_suffixes[] = { "F", "", "L", "F16", "F32",
161                                                "F64", "F128", "F32X", "F64X",
162                                                "F128X", NULL };
163 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
164
165 static const char *const *const suffix_lists[] = {
166   flt_suffixes,
167   int_suffixes,
168   NULL
169 };
170
171 int
172 main (int argc, char **argv)
173 {
174   /* Check arguments.  */
175   progname = argv[0];
176   if (argc != 2
177       || argv[1][0] != '-'
178       || !strchr ("co", argv[1][1])
179       || argv[1][2])
180     fatal ("usage: %s [-c|-o] > file", progname);
181   int type = argv[1][1];
182
183   /* Collect the set of built-in and internal functions.  */
184   string_set builtins;
185   string_set internal_fns;
186   add_to_set (&builtins, builtin_names);
187   add_to_set (&internal_fns, internal_fn_flt_names);
188   add_to_set (&internal_fns, internal_fn_int_names);
189
190   /* Check the functions.  */
191   for (unsigned int i = 0; internal_fn_flt_names[i]; ++i)
192     {
193       const char *name = internal_fn_flt_names[i];
194       if (!is_group (&builtins, name, flt_suffixes))
195         error ("DEF_INTERNAL_FLT_FN (%s) has no associated built-in"
196                " functions", name);
197     }
198   for (unsigned int i = 0; internal_fn_int_names[i]; ++i)
199     {
200       const char *name = internal_fn_int_names[i];
201       if (!is_group (&builtins, name, int_suffixes))
202         error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in"
203                " functions", name);
204     }
205
206   /* Go through the built-in functions in declaration order, outputting
207      definitions as appropriate.  */
208   for (unsigned int i = 0; builtin_names[i]; ++i)
209     {
210       const char *name = builtin_names[i];
211       if (strncmp (name, "BUILT_IN_", 9) == 0)
212         {
213           const char *root = name + 9;
214           for (unsigned int j = 0; suffix_lists[j]; ++j)
215             {
216               const char *const *const suffix = suffix_lists[j];
217
218               if (is_group (&builtins, root, suffix))
219                 {
220                   bool internal_p = internal_fns.contains (root);
221
222                   if (type == 'c')
223                     print_case_cfn (root, internal_p, suffix, "");
224                   else
225                     print_define_operator_list (root, internal_p, suffix, "");
226
227                       /* Support the _Float<N> and _Float<N>X math functions if
228                          they exist.  We put these out as a separate CFN or
229                          operator macro, so code can add support or not as
230                          needed.  We also put out a combined CFN or operator
231                          macro that includes both the traditional names and the
232                          _Float<N> and _Float<N>X versions.  */
233                   if (suffix == flt_suffixes
234                       && is_group (&builtins, root, fltfn_suffixes))
235                     {
236                       if (type == 'c')
237                         {
238                           print_case_cfn (root, false, fltfn_suffixes, "_FN");
239                           print_case_cfn (root, false, fltall_suffixes, "_ALL");
240                         }
241                       else
242                         {
243                           print_define_operator_list (root, false,
244                                                       fltfn_suffixes, "_FN");
245                           print_define_operator_list (root, internal_p,
246                                                       fltall_suffixes, "_ALL");
247                         }
248                     }
249                 }
250             }
251         }
252     }
253
254   if (fflush (stdout) || fclose (stdout) || have_error)
255     return FATAL_EXIT_CODE;
256   return SUCCESS_EXIT_CODE;
257 }