Mercurial > hg > CbC > CbC_gcc
comparison gcc/gencfn-macros.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Generate macros based on the combined_fn enum. | |
2 Copyright (C) 2015-2017 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. */ | |
98 | |
99 static void | |
100 print_case_cfn (const char *name, bool internal_p, | |
101 const char *const *suffixes) | |
102 { | |
103 printf ("#define CASE_CFN_%s", name); | |
104 if (internal_p) | |
105 printf (" \\\n case CFN_%s", name); | |
106 for (unsigned int i = 0; suffixes[i]; ++i) | |
107 printf ("%s \\\n case CFN_BUILT_IN_%s%s", | |
108 internal_p || i > 0 ? ":" : "", name, suffixes[i]); | |
109 printf ("\n"); | |
110 } | |
111 | |
112 /* Print an operator list for all combined functions related to NAME, | |
113 with the null-terminated list of suffixes in SUFFIXES. INTERNAL_P | |
114 says whether CFN_<NAME> also exists. */ | |
115 | |
116 static void | |
117 print_define_operator_list (const char *name, bool internal_p, | |
118 const char *const *suffixes) | |
119 { | |
120 printf ("(define_operator_list %s\n", name); | |
121 for (unsigned int i = 0; suffixes[i]; ++i) | |
122 printf (" BUILT_IN_%s%s\n", name, suffixes[i]); | |
123 if (internal_p) | |
124 printf (" IFN_%s)\n", name); | |
125 else | |
126 printf (" null)\n"); | |
127 } | |
128 | |
129 const char *const builtin_names[] = { | |
130 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \ | |
131 #ENUM, | |
132 #include "builtins.def" | |
133 NULL | |
134 }; | |
135 | |
136 const char *const internal_fn_flt_names[] = { | |
137 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \ | |
138 #NAME, | |
139 #include "internal-fn.def" | |
140 NULL | |
141 }; | |
142 | |
143 const char *const internal_fn_int_names[] = { | |
144 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \ | |
145 #NAME, | |
146 #include "internal-fn.def" | |
147 NULL | |
148 }; | |
149 | |
150 static const char *const flt_suffixes[] = { "F", "", "L", NULL }; | |
151 static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL }; | |
152 | |
153 static const char *const *const suffix_lists[] = { | |
154 flt_suffixes, | |
155 int_suffixes, | |
156 NULL | |
157 }; | |
158 | |
159 int | |
160 main (int argc, char **argv) | |
161 { | |
162 /* Check arguments. */ | |
163 progname = argv[0]; | |
164 if (argc != 2 | |
165 || argv[1][0] != '-' | |
166 || !strchr ("co", argv[1][1]) | |
167 || argv[1][2]) | |
168 fatal ("usage: %s [-c|-o] > file", progname); | |
169 int type = argv[1][1]; | |
170 | |
171 /* Collect the set of built-in and internal functions. */ | |
172 string_set builtins; | |
173 string_set internal_fns; | |
174 add_to_set (&builtins, builtin_names); | |
175 add_to_set (&internal_fns, internal_fn_flt_names); | |
176 add_to_set (&internal_fns, internal_fn_int_names); | |
177 | |
178 /* Check the functions. */ | |
179 for (unsigned int i = 0; internal_fn_flt_names[i]; ++i) | |
180 { | |
181 const char *name = internal_fn_flt_names[i]; | |
182 if (!is_group (&builtins, name, flt_suffixes)) | |
183 error ("DEF_INTERNAL_FLT_FN (%s) has no associated built-in" | |
184 " functions", name); | |
185 } | |
186 for (unsigned int i = 0; internal_fn_int_names[i]; ++i) | |
187 { | |
188 const char *name = internal_fn_int_names[i]; | |
189 if (!is_group (&builtins, name, int_suffixes)) | |
190 error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in" | |
191 " functions", name); | |
192 } | |
193 | |
194 /* Go through the built-in functions in declaration order, outputting | |
195 definitions as appropriate. */ | |
196 for (unsigned int i = 0; builtin_names[i]; ++i) | |
197 { | |
198 const char *name = builtin_names[i]; | |
199 if (strncmp (name, "BUILT_IN_", 9) == 0) | |
200 { | |
201 const char *root = name + 9; | |
202 for (unsigned int j = 0; suffix_lists[j]; ++j) | |
203 if (is_group (&builtins, root, suffix_lists[j])) | |
204 { | |
205 bool internal_p = internal_fns.contains (root); | |
206 if (type == 'c') | |
207 print_case_cfn (root, internal_p, suffix_lists[j]); | |
208 else | |
209 print_define_operator_list (root, internal_p, | |
210 suffix_lists[j]); | |
211 } | |
212 } | |
213 } | |
214 | |
215 if (fflush (stdout) || fclose (stdout) || have_error) | |
216 return FATAL_EXIT_CODE; | |
217 return SUCCESS_EXIT_CODE; | |
218 } |