Branch data Line data Source code
1 : : /* m2builtins.cc provides an interface to the GCC builtins.
2 : :
3 : : Copyright (C) 2012-2025 Free Software Foundation, Inc.
4 : : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5 : :
6 : : This file is part of GNU Modula-2.
7 : :
8 : : GNU Modula-2 is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3, or (at your option)
11 : : any later version.
12 : :
13 : : GNU Modula-2 is distributed in the hope that it will be useful, but
14 : : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with GNU Modula-2; see the file COPYING3. If not see
20 : : <http://www.gnu.org/licenses/>. */
21 : :
22 : : #include "gcc-consolidation.h"
23 : :
24 : : #include "m2block.h"
25 : : #include "m2convert.h"
26 : : #include "m2decl.h"
27 : : #include "m2expr.h"
28 : : #include "m2statement.h"
29 : : #include "m2tree.h"
30 : : #include "m2treelib.h"
31 : : #include "m2type.h"
32 : : #include "m2configure.h"
33 : :
34 : : #undef DEBUGGING
35 : :
36 : : #define GM2
37 : : #define GM2_BUG_REPORT \
38 : : "Please report this crash to the GNU Modula-2 mailing list " \
39 : : "<gm2@nongnu.org>\n"
40 : :
41 : : #define ASSERT(X, Y) \
42 : : { \
43 : : if (!(X)) \
44 : : { \
45 : : debug_tree (Y); \
46 : : internal_error ("%s:%d:assertion of condition %qs failed", __FILE__, __LINE__, \
47 : : #X); \
48 : : } \
49 : : }
50 : : #define ERROR(X) \
51 : : { \
52 : : internal_error ("%s:%d:%s", __FILE__, __LINE__, X); \
53 : : }
54 : :
55 : : typedef enum {
56 : : BT_FN_NONE,
57 : : BT_FN_PTR_SIZE,
58 : : BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE,
59 : : BT_FN_FLOAT,
60 : : BT_FN_DOUBLE,
61 : : BT_FN_LONG_DOUBLE,
62 : : BT_FN_FLOAT_FLOAT,
63 : : BT_FN_DOUBLE_DOUBLE,
64 : : BT_FN_LONG_DOUBLE_LONG_DOUBLE,
65 : : BT_FN_STRING_CONST_STRING_INT,
66 : : BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
67 : : BT_FN_TRAD_PTR_PTR_INT_SIZE,
68 : : BT_FN_STRING_STRING_CONST_STRING,
69 : : BT_FN_STRING_STRING_CONST_STRING_SIZE,
70 : : BT_FN_INT_CONST_STRING_CONST_STRING,
71 : : BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
72 : : BT_FN_INT_CONST_STRING,
73 : : BT_FN_STRING_CONST_STRING_CONST_STRING,
74 : : BT_FN_SIZE_CONST_STRING_CONST_STRING,
75 : : BT_FN_PTR_UNSIGNED,
76 : : BT_FN_VOID_PTR_INT,
77 : : BT_FN_INT_PTR,
78 : : BT_FN_INT_FLOAT,
79 : : BT_FN_INT_DOUBLE,
80 : : BT_FN_INT_LONG_DOUBLE,
81 : : BT_FN_FLOAT_FCOMPLEX,
82 : : BT_FN_DOUBLE_DCOMPLEX,
83 : : BT_FN_LONG_DOUBLE_LDCOMPLEX,
84 : :
85 : : BT_FN_FCOMPLEX_FCOMPLEX,
86 : : BT_FN_DCOMPLEX_DCOMPLEX,
87 : : BT_FN_LDCOMPLEX_LDCOMPLEX,
88 : :
89 : : BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX,
90 : : BT_FN_FCOMPLEX_FLOAT_FCOMPLEX,
91 : : BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX,
92 : :
93 : : BT_FN_FLOAT_FLOAT_FLOATPTR,
94 : : BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
95 : : BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR,
96 : :
97 : : BT_FN_FLOAT_FLOAT_LONG_DOUBLE,
98 : : BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE,
99 : : BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE,
100 : :
101 : : BT_FN_FLOAT_FLOAT_LONG,
102 : : BT_FN_DOUBLE_DOUBLE_LONG,
103 : : BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG,
104 : :
105 : : BT_FN_FLOAT_FLOAT_INT,
106 : : BT_FN_DOUBLE_DOUBLE_INT,
107 : : BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT,
108 : :
109 : : BT_FN_FLOAT_FLOAT_FLOAT,
110 : : BT_FN_DOUBLE_DOUBLE_DOUBLE,
111 : : } builtin_prototype;
112 : :
113 : : typedef enum
114 : : {
115 : : bf_true,
116 : : bf_false,
117 : : bf_extension_lib,
118 : : bf_default_lib,
119 : : bf_gcc,
120 : : bf_c99,
121 : : bf_c99_c90res,
122 : : bf_extension_lib_floatn,
123 : : bf_c99_compl,
124 : : } bf_category;
125 : :
126 : : struct builtin_function_entry
127 : : {
128 : : const char *name;
129 : : builtin_prototype defn;
130 : : int function_code;
131 : : enum built_in_class fclass;
132 : : const char *library_name;
133 : : tree function_node;
134 : : tree return_node;
135 : : bf_category function_avail;
136 : : };
137 : :
138 : : /* Entries are added by examining gcc/builtins.def and copying those
139 : : functions which can be applied to Modula-2. */
140 : :
141 : : static struct GTY(()) builtin_function_entry list_of_builtins[] = {
142 : : { "__builtin_alloca", BT_FN_PTR_SIZE, BUILT_IN_ALLOCA, BUILT_IN_NORMAL,
143 : : "alloca", NULL, NULL, bf_extension_lib },
144 : : { "__builtin_memcpy", BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE, BUILT_IN_MEMCPY,
145 : : BUILT_IN_NORMAL, "memcpy", NULL, NULL, bf_default_lib },
146 : : { "__builtin_isfinite", BT_FN_INT_DOUBLE, BUILT_IN_ISFINITE, BUILT_IN_NORMAL,
147 : : "isfinite", NULL, NULL, bf_gcc },
148 : : { "__builtin_isnan", BT_FN_INT_DOUBLE, BUILT_IN_ISNAN, BUILT_IN_NORMAL,
149 : : "isnan", NULL, NULL, bf_gcc },
150 : : { "__builtin_sinf", BT_FN_FLOAT_FLOAT, BUILT_IN_SINF, BUILT_IN_NORMAL,
151 : : "sinf", NULL, NULL, bf_c99_c90res },
152 : : { "__builtin_sin", BT_FN_DOUBLE_DOUBLE, BUILT_IN_SIN, BUILT_IN_NORMAL, "sin",
153 : : NULL, NULL, bf_c99_c90res },
154 : : { "__builtin_sinl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_SINL,
155 : : BUILT_IN_NORMAL, "sinl", NULL, NULL, bf_c99_c90res },
156 : : { "__builtin_cosf", BT_FN_FLOAT_FLOAT, BUILT_IN_SINF, BUILT_IN_NORMAL,
157 : : "cosf", NULL, NULL, bf_c99_c90res },
158 : : { "__builtin_cos", BT_FN_DOUBLE_DOUBLE, BUILT_IN_COS, BUILT_IN_NORMAL, "cos",
159 : : NULL, NULL, bf_c99_c90res },
160 : : { "__builtin_cosl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_COSL,
161 : : BUILT_IN_NORMAL, "cosl", NULL, NULL, bf_c99_c90res },
162 : : { "__builtin_sqrtf", BT_FN_FLOAT_FLOAT, BUILT_IN_SQRTF, BUILT_IN_NORMAL,
163 : : "sqrtf", NULL, NULL, bf_c99_c90res },
164 : : { "__builtin_sqrt", BT_FN_DOUBLE_DOUBLE, BUILT_IN_SQRT, BUILT_IN_NORMAL,
165 : : "sqrt", NULL, NULL, bf_default_lib },
166 : : { "__builtin_sqrtl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_SQRTL,
167 : : BUILT_IN_NORMAL, "sqrtl", NULL, NULL, bf_c99_c90res },
168 : : { "__builtin_fabsf", BT_FN_FLOAT_FLOAT, BUILT_IN_FABSF, BUILT_IN_NORMAL,
169 : : "fabsf", NULL, NULL, bf_c99_c90res },
170 : : { "__builtin_fabs", BT_FN_DOUBLE_DOUBLE, BUILT_IN_FABS, BUILT_IN_NORMAL,
171 : : "fabs", NULL, NULL, bf_default_lib },
172 : : { "__builtin_fabsl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_FABSL,
173 : : BUILT_IN_NORMAL, "fabsl", NULL, NULL, bf_c99_c90res },
174 : : { "__builtin_logf", BT_FN_FLOAT_FLOAT, BUILT_IN_LOGF, BUILT_IN_NORMAL,
175 : : "logf", NULL, NULL, bf_c99_c90res },
176 : : { "__builtin_log", BT_FN_DOUBLE_DOUBLE, BUILT_IN_LOG, BUILT_IN_NORMAL, "log",
177 : : NULL, NULL, bf_extension_lib_floatn },
178 : : { "__builtin_logl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_LOGL,
179 : : BUILT_IN_NORMAL, "logl", NULL, NULL, bf_c99_c90res },
180 : : { "__builtin_expf", BT_FN_FLOAT_FLOAT, BUILT_IN_EXPF, BUILT_IN_NORMAL,
181 : : "expf", NULL, NULL, bf_c99_c90res },
182 : : { "__builtin_exp", BT_FN_DOUBLE_DOUBLE, BUILT_IN_EXP, BUILT_IN_NORMAL, "exp",
183 : : NULL, NULL, bf_extension_lib_floatn },
184 : : { "__builtin_expl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_EXPL,
185 : : BUILT_IN_NORMAL, "expl", NULL, NULL, bf_c99_c90res },
186 : : { "__builtin_log10f", BT_FN_FLOAT_FLOAT, BUILT_IN_LOG10F, BUILT_IN_NORMAL,
187 : : "log10f", NULL, NULL, bf_c99_c90res },
188 : : { "__builtin_log10", BT_FN_DOUBLE_DOUBLE, BUILT_IN_LOG10, BUILT_IN_NORMAL,
189 : : "log10", NULL, NULL, bf_default_lib },
190 : : { "__builtin_log10l", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_LOG10L,
191 : : BUILT_IN_NORMAL, "log10l", NULL, NULL, bf_c99_c90res },
192 : : { "__builtin_ilogbf", BT_FN_INT_FLOAT, BUILT_IN_ILOGBF, BUILT_IN_NORMAL,
193 : : "ilogbf", NULL, NULL, bf_c99 },
194 : : { "__builtin_ilogb", BT_FN_INT_DOUBLE, BUILT_IN_ILOGB, BUILT_IN_NORMAL,
195 : : "ilogb", NULL, NULL, bf_c99 },
196 : : { "__builtin_ilogbl", BT_FN_INT_LONG_DOUBLE, BUILT_IN_ILOGBL,
197 : : BUILT_IN_NORMAL, "ilogbl", NULL, NULL, bf_c99 },
198 : :
199 : : { "__builtin_atan2f", BT_FN_FLOAT_FLOAT_FLOAT, BUILT_IN_ATAN2F,
200 : : BUILT_IN_NORMAL, "atan2f", NULL, NULL, bf_c99_c90res },
201 : : { "__builtin_atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, BUILT_IN_ATAN2,
202 : : BUILT_IN_NORMAL, "atan2", NULL, NULL, bf_default_lib },
203 : : { "__builtin_atan2l", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE,
204 : : BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL, NULL, bf_c99_c90res },
205 : :
206 : : { "__builtin_signbit", BT_FN_INT_DOUBLE, BUILT_IN_SIGNBIT, BUILT_IN_NORMAL,
207 : : "signbit", NULL, NULL, bf_extension_lib },
208 : : { "__builtin_signbitf", BT_FN_INT_FLOAT, BUILT_IN_SIGNBITF, BUILT_IN_NORMAL,
209 : : "signbitf", NULL, NULL, bf_extension_lib },
210 : : { "__builtin_signbitl", BT_FN_INT_LONG_DOUBLE, BUILT_IN_SIGNBITL,
211 : : BUILT_IN_NORMAL, "signbitl", NULL, NULL, bf_extension_lib },
212 : : { "__builtin_modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, BUILT_IN_MODF,
213 : : BUILT_IN_NORMAL, "modf", NULL, NULL, bf_default_lib },
214 : : { "__builtin_modff", BT_FN_FLOAT_FLOAT_FLOATPTR, BUILT_IN_MODFF,
215 : : BUILT_IN_NORMAL, "modff", NULL, NULL, bf_c99_c90res },
216 : : { "__builtin_modfl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR,
217 : : BUILT_IN_MODFL, BUILT_IN_NORMAL, "modfl", NULL, NULL, bf_c99_c90res },
218 : : { "__builtin_nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, BUILT_IN_NEXTAFTER,
219 : : BUILT_IN_NORMAL, "nextafter", NULL, NULL, bf_c99 },
220 : : { "__builtin_nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, BUILT_IN_NEXTAFTERF,
221 : : BUILT_IN_NORMAL, "nextafterf", NULL, NULL, bf_c99 },
222 : : { "__builtin_nextafterl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE,
223 : : BUILT_IN_NEXTAFTERL, BUILT_IN_NORMAL, "nextafterl", NULL, NULL, bf_c99 },
224 : : { "__builtin_nexttoward", BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE,
225 : : BUILT_IN_NEXTTOWARD, BUILT_IN_NORMAL, "nexttoward", NULL, NULL, bf_c99 },
226 : : { "__builtin_nexttowardf", BT_FN_FLOAT_FLOAT_LONG_DOUBLE,
227 : : BUILT_IN_NEXTTOWARDF, BUILT_IN_NORMAL, "nexttowardf", NULL, NULL, bf_c99 },
228 : : { "__builtin_nexttowardl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE,
229 : : BUILT_IN_NEXTTOWARDL, BUILT_IN_NORMAL, "nexttowardl", NULL, NULL, bf_c99 },
230 : : { "__builtin_scalbln", BT_FN_DOUBLE_DOUBLE_LONG, BUILT_IN_SCALBLN,
231 : : BUILT_IN_NORMAL, "scalbln", NULL, NULL, bf_extension_lib },
232 : : { "__builtin_scalblnf", BT_FN_FLOAT_FLOAT_LONG, BUILT_IN_SCALBLNF,
233 : : BUILT_IN_NORMAL, "scalblnf", NULL, NULL, bf_extension_lib },
234 : : { "__builtin_scalblnl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG,
235 : : BUILT_IN_SCALBLNL, BUILT_IN_NORMAL, "scalblnl", NULL, NULL, bf_extension_lib },
236 : : { "__builtin_scalbn", BT_FN_DOUBLE_DOUBLE_INT, BUILT_IN_SCALBN,
237 : : BUILT_IN_NORMAL, "scalbln", NULL, NULL, bf_extension_lib },
238 : : { "__builtin_scalbnf", BT_FN_FLOAT_FLOAT_INT, BUILT_IN_SCALBNF,
239 : : BUILT_IN_NORMAL, "scalblnf", NULL, NULL, bf_extension_lib },
240 : : { "__builtin_scalbnl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT, BUILT_IN_SCALBNL,
241 : : BUILT_IN_NORMAL, "scalblnl", NULL, NULL, bf_extension_lib },
242 : :
243 : : /* Complex intrinsic functions. */
244 : : { "__builtin_cabs", BT_FN_DOUBLE_DCOMPLEX, BUILT_IN_CABS, BUILT_IN_NORMAL,
245 : : "cabs", NULL, NULL, bf_c99_compl },
246 : : { "__builtin_cabsf", BT_FN_FLOAT_FCOMPLEX, BUILT_IN_CABSF, BUILT_IN_NORMAL,
247 : : "cabsf", NULL, NULL, bf_c99_compl },
248 : : { "__builtin_cabsl", BT_FN_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CABSL,
249 : : BUILT_IN_NORMAL, "cabsl", NULL, NULL, bf_c99_compl },
250 : :
251 : : { "__builtin_carg", BT_FN_DOUBLE_DCOMPLEX, BUILT_IN_CABS, BUILT_IN_NORMAL,
252 : : "carg", NULL, NULL, bf_c99_compl },
253 : : { "__builtin_cargf", BT_FN_FLOAT_FCOMPLEX, BUILT_IN_CABSF, BUILT_IN_NORMAL,
254 : : "cargf", NULL, NULL, bf_c99_compl },
255 : : { "__builtin_cargl", BT_FN_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CABSL,
256 : : BUILT_IN_NORMAL, "cargl", NULL, NULL, bf_c99_compl },
257 : :
258 : : { "__builtin_conj", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CONJ, BUILT_IN_NORMAL,
259 : : "carg", NULL, NULL, bf_c99_compl },
260 : : { "__builtin_conjf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CONJF,
261 : : BUILT_IN_NORMAL, "conjf", NULL, NULL, bf_c99_compl },
262 : : { "__builtin_conjl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CONJL,
263 : : BUILT_IN_NORMAL, "conjl", NULL, NULL, bf_c99_compl },
264 : :
265 : : { "__builtin_cpow", BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX, BUILT_IN_CPOW,
266 : : BUILT_IN_NORMAL, "cpow", NULL, NULL, bf_c99_compl },
267 : : { "__builtin_cpowf", BT_FN_FCOMPLEX_FLOAT_FCOMPLEX, BUILT_IN_CPOWF,
268 : : BUILT_IN_NORMAL, "cpowf", NULL, NULL, bf_c99_compl },
269 : : { "__builtin_cpowl", BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CPOWL,
270 : : BUILT_IN_NORMAL, "cpowl", NULL, NULL, bf_c99_compl },
271 : :
272 : : { "__builtin_csqrt", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CSQRT,
273 : : BUILT_IN_NORMAL, "csqrt", NULL, NULL, bf_c99_compl },
274 : : { "__builtin_csqrtf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CSQRTF,
275 : : BUILT_IN_NORMAL, "csqrtf", NULL, NULL, bf_c99_compl },
276 : : { "__builtin_csqrtl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CSQRTL,
277 : : BUILT_IN_NORMAL, "csqrtl", NULL, NULL, bf_c99_compl },
278 : :
279 : : { "__builtin_cexp", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CEXP, BUILT_IN_NORMAL,
280 : : "cexp", NULL, NULL, bf_c99_compl },
281 : : { "__builtin_cexpf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CEXPF,
282 : : BUILT_IN_NORMAL, "cexpf", NULL, NULL, bf_c99_compl },
283 : : { "__builtin_cexpl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CEXPL,
284 : : BUILT_IN_NORMAL, "cexpl", NULL, NULL, bf_c99_compl },
285 : :
286 : : { "__builtin_clog", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CLOG, BUILT_IN_NORMAL,
287 : : "clog", NULL, NULL, bf_c99_compl },
288 : : { "__builtin_clogf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CLOGF, BUILT_IN_NORMAL,
289 : : "clogf", NULL, NULL, bf_c99_compl },
290 : : { "__builtin_clogl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CLOGL,
291 : : BUILT_IN_NORMAL, "clogl", NULL, NULL, bf_c99_compl },
292 : :
293 : : { "__builtin_csin", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CSIN, BUILT_IN_NORMAL,
294 : : "csin", NULL, NULL, bf_c99_compl },
295 : : { "__builtin_csinf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CSINF,
296 : : BUILT_IN_NORMAL, "csinf", NULL, NULL, bf_c99_compl },
297 : : { "__builtin_csinl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CSINL,
298 : : BUILT_IN_NORMAL, "csinl", NULL, NULL, bf_c99_compl },
299 : :
300 : : { "__builtin_ccos", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CCOS, BUILT_IN_NORMAL,
301 : : "ccos", NULL, NULL, bf_c99_compl },
302 : : { "__builtin_ccosf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CCOSF,
303 : : BUILT_IN_NORMAL, "ccosf", NULL, NULL, bf_c99_compl },
304 : : { "__builtin_ccosl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CCOSL,
305 : : BUILT_IN_NORMAL, "ccosl", NULL, NULL, bf_c99_compl },
306 : :
307 : : { "__builtin_ctan", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CTAN, BUILT_IN_NORMAL,
308 : : "ctan", NULL, NULL, bf_c99_compl },
309 : : { "__builtin_ctanf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CTANF,
310 : : BUILT_IN_NORMAL, "ctanf", NULL, NULL, bf_c99_compl },
311 : : { "__builtin_ctanl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CTANL,
312 : : BUILT_IN_NORMAL, "ctanl", NULL, NULL, bf_c99_compl },
313 : :
314 : : { "__builtin_casin", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CASIN,
315 : : BUILT_IN_NORMAL, "casin", NULL, NULL, bf_c99_compl },
316 : : { "__builtin_casinf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CASINF,
317 : : BUILT_IN_NORMAL, "casinf", NULL, NULL, bf_c99_compl },
318 : : { "__builtin_casinl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CASINL,
319 : : BUILT_IN_NORMAL, "casinl", NULL, NULL, bf_c99_compl },
320 : :
321 : : { "__builtin_cacos", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CACOS,
322 : : BUILT_IN_NORMAL, "cacos", NULL, NULL, bf_c99_compl },
323 : : { "__builtin_cacosf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CACOSF,
324 : : BUILT_IN_NORMAL, "cacosf", NULL, NULL, bf_c99_compl },
325 : : { "__builtin_cacosl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CACOSL,
326 : : BUILT_IN_NORMAL, "cacosl", NULL, NULL, bf_c99_compl },
327 : :
328 : : { "__builtin_catan", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CATAN,
329 : : BUILT_IN_NORMAL, "catan", NULL, NULL, bf_c99_compl },
330 : : { "__builtin_catanf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CATANF,
331 : : BUILT_IN_NORMAL, "catanf", NULL, NULL, bf_c99_compl },
332 : : { "__builtin_catanl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CATANL,
333 : : BUILT_IN_NORMAL, "catanl", NULL, NULL, bf_c99_compl },
334 : :
335 : : { "__builtin_huge_val", BT_FN_DOUBLE, BUILT_IN_HUGE_VAL, BUILT_IN_NORMAL,
336 : : "huge_val", NULL, NULL, bf_gcc },
337 : : { "__builtin_huge_valf", BT_FN_FLOAT, BUILT_IN_HUGE_VALF, BUILT_IN_NORMAL,
338 : : "huge_valf", NULL, NULL, bf_gcc },
339 : : { "__builtin_huge_vall", BT_FN_LONG_DOUBLE, BUILT_IN_HUGE_VALL,
340 : : BUILT_IN_NORMAL, "huge_vall", NULL, NULL, bf_gcc },
341 : :
342 : : { "__builtin_index", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_INDEX,
343 : : BUILT_IN_NORMAL, "index", NULL, NULL, bf_extension_lib },
344 : : { "__builtin_rindex", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_RINDEX,
345 : : BUILT_IN_NORMAL, "rindex", NULL, NULL, bf_extension_lib },
346 : : { "__builtin_memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, BUILT_IN_MEMCMP,
347 : : BUILT_IN_NORMAL, "memcmp", NULL, NULL, bf_default_lib },
348 : : { "__builtin_memmove", BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE, BUILT_IN_MEMMOVE,
349 : : BUILT_IN_NORMAL, "memmove", NULL, NULL, bf_default_lib },
350 : : { "__builtin_memset", BT_FN_TRAD_PTR_PTR_INT_SIZE, BUILT_IN_MEMSET,
351 : : BUILT_IN_NORMAL, "memset", NULL, NULL, bf_default_lib },
352 : : { "__builtin_strcat", BT_FN_STRING_STRING_CONST_STRING, BUILT_IN_STRCAT,
353 : : BUILT_IN_NORMAL, "strcat", NULL, NULL, bf_default_lib },
354 : : { "__builtin_strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE,
355 : : BUILT_IN_STRNCAT, BUILT_IN_NORMAL, "strncat", NULL, NULL, bf_default_lib },
356 : : { "__builtin_strcpy", BT_FN_STRING_STRING_CONST_STRING, BUILT_IN_STRCPY,
357 : : BUILT_IN_NORMAL, "strcpy", NULL, NULL, bf_default_lib },
358 : : { "__builtin_strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE,
359 : : BUILT_IN_STRNCPY, BUILT_IN_NORMAL, "strncpy", NULL, NULL, bf_default_lib },
360 : : { "__builtin_strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, BUILT_IN_STRCMP,
361 : : BUILT_IN_NORMAL, "strcmp", NULL, NULL, bf_default_lib },
362 : : { "__builtin_strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
363 : : BUILT_IN_STRNCMP, BUILT_IN_NORMAL, "strncmp", NULL, NULL, bf_default_lib },
364 : : { "__builtin_strlen", BT_FN_INT_CONST_STRING, BUILT_IN_STRLEN,
365 : : BUILT_IN_NORMAL, "strlen", NULL, NULL, bf_default_lib },
366 : : { "__builtin_strstr", BT_FN_STRING_CONST_STRING_CONST_STRING,
367 : : BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr", NULL, NULL, bf_default_lib },
368 : : { "__builtin_strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING,
369 : : BUILT_IN_STRPBRK, BUILT_IN_NORMAL, "strpbrk", NULL, NULL, bf_default_lib },
370 : : { "__builtin_strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, BUILT_IN_STRSPN,
371 : : BUILT_IN_NORMAL, "strspn", NULL, NULL, bf_default_lib },
372 : : { "__builtin_strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING,
373 : : BUILT_IN_STRCSPN, BUILT_IN_NORMAL, "strcspn", NULL, NULL, bf_default_lib },
374 : : { "__builtin_strchr", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_STRCHR,
375 : : BUILT_IN_NORMAL, "strchr", NULL, NULL, bf_default_lib },
376 : : { "__builtin_strrchr", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_STRCHR,
377 : : BUILT_IN_NORMAL, "strrchr", NULL, NULL, bf_default_lib },
378 : :
379 : : { "__builtin_frame_address", BT_FN_PTR_UNSIGNED, BUILT_IN_FRAME_ADDRESS,
380 : : BUILT_IN_NORMAL, "frame_address", NULL, NULL, bf_gcc },
381 : : { "__builtin_return_address", BT_FN_PTR_UNSIGNED, BUILT_IN_RETURN_ADDRESS,
382 : : BUILT_IN_NORMAL, "return_address", NULL, NULL, bf_gcc },
383 : : { "__builtin_longjmp", BT_FN_VOID_PTR_INT, BUILT_IN_LONGJMP, BUILT_IN_NORMAL,
384 : : "longjmp", NULL, NULL, bf_gcc },
385 : : { "__builtin_setjmp", BT_FN_INT_PTR, BUILT_IN_SETJMP, BUILT_IN_NORMAL,
386 : : "setjmp", NULL, NULL, bf_gcc },
387 : : { NULL, BT_FN_NONE, 0, NOT_BUILT_IN, "", NULL, NULL, bf_false}
388 : : };
389 : :
390 : : struct builtin_type_info
391 : : {
392 : : const char *name;
393 : : unsigned int returnType;
394 : : tree (*functionHandler) (location_t, tree);
395 : : };
396 : :
397 : : struct GTY(()) builtin_macro_definition
398 : : {
399 : : const char *name;
400 : : const char *builtinname;
401 : : tree function_node;
402 : : tree return_node;
403 : : };
404 : :
405 : : static GTY (()) tree sizetype_endlink;
406 : : static GTY (()) tree unsigned_endlink;
407 : : static GTY (()) tree endlink;
408 : : static GTY (()) tree math_endlink;
409 : : static GTY (()) tree int_endlink;
410 : : static GTY (()) tree ptr_endlink;
411 : : static GTY (()) tree const_ptr_endlink;
412 : : static GTY (()) tree double_ftype_void;
413 : : static GTY (()) tree float_ftype_void;
414 : : static GTY (()) tree ldouble_ftype_void;
415 : : static GTY (()) tree float_ftype_float;
416 : : static GTY (()) tree double_ftype_double;
417 : : static GTY (()) tree ldouble_ftype_ldouble;
418 : : static GTY (()) tree gm2_alloca_node;
419 : : static GTY (()) tree gm2_memcpy_node;
420 : : static GTY (()) tree gm2_memset_node;
421 : : static GTY (()) tree gm2_isfinite_node;
422 : : static GTY (()) tree gm2_isnan_node;
423 : : static GTY (()) tree gm2_huge_valf_node;
424 : : static GTY (()) tree gm2_huge_val_node;
425 : : static GTY (()) tree gm2_huge_vall_node;
426 : : static GTY (()) tree long_doubleptr_type_node;
427 : : static GTY (()) tree doubleptr_type_node;
428 : : static GTY (()) tree floatptr_type_node;
429 : : static GTY (()) tree builtin_ftype_int_var;
430 : : static GTY (()) tree builtin_ftype_int_uint;
431 : : static GTY (()) tree builtin_ftype_int_ulong;
432 : : static GTY (()) tree builtin_ftype_int_ulonglong;
433 : : static GTY (()) vec<builtin_macro_definition, va_gc> *builtin_macros;
434 : :
435 : : /* Prototypes for locally defined functions. */
436 : : static tree DoBuiltinAlloca (location_t location, tree n);
437 : : static tree DoBuiltinMemCopy (location_t location, tree dest, tree src,
438 : : tree n);
439 : : static tree DoBuiltinIsfinite (location_t location, tree value);
440 : : static tree DoBuiltinIsnan (location_t location, tree value);
441 : : static void create_function_prototype (location_t location,
442 : : struct builtin_function_entry *fe);
443 : : static tree doradix (location_t location, tree type);
444 : : static tree doplaces (location_t location, tree type);
445 : : static tree doexponentmin (location_t location, tree type);
446 : : static tree doexponentmax (location_t location, tree type);
447 : : static tree dolarge (location_t location, tree type);
448 : : static tree dosmall (location_t location, tree type);
449 : : static tree doiec559 (location_t location, tree type);
450 : : static tree dolia1 (location_t location, tree type);
451 : : static tree doiso (location_t location, tree type);
452 : : static tree doieee (location_t location, tree type);
453 : : static tree dorounds (location_t location, tree type);
454 : : static tree dogUnderflow (location_t location, tree type);
455 : : static tree doexception (location_t location, tree type);
456 : : static tree doextend (location_t location, tree type);
457 : : static tree donModes (location_t location, tree type);
458 : : /* Prototypes finish here. */
459 : :
460 : : #define m2builtins_c
461 : : #include "m2builtins.h"
462 : :
463 : : static struct builtin_type_info m2_type_info[] = {
464 : : { "radix", 2, doradix },
465 : : { "places", 2, doplaces },
466 : : { "expoMin", 2, doexponentmin },
467 : : { "expoMax", 2, doexponentmax },
468 : : { "large", 3, dolarge },
469 : : { "small", 3, dosmall },
470 : : { "IEC559", 1, doiec559 },
471 : : { "LIA1", 1, dolia1 },
472 : : { "ISO", 1, doiso },
473 : : { "IEEE", 1, doieee },
474 : : { "rounds", 1, dorounds },
475 : : { "gUnderflow", 1, dogUnderflow },
476 : : { "exception", 1, doexception },
477 : : { "extend", 1, doextend },
478 : : { "nModes", 2, donModes },
479 : : { NULL, 0, NULL },
480 : : };
481 : :
482 : : /* Return a definition for a builtin function named NAME and whose
483 : : data type is TYPE. TYPE should be a function type with argument
484 : : types. FUNCTION_CODE tells later passes how to compile calls to this
485 : : function. See tree.h for its possible values.
486 : :
487 : : If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, the
488 : : name to be called if we can't opencode the function. */
489 : :
490 : : tree
491 : 1795005 : builtin_function (location_t location, const char *name, tree type,
492 : : int function_code, enum built_in_class fclass,
493 : : const char *library_name, tree attrs)
494 : : {
495 : 1795005 : tree decl = add_builtin_function (name, type, function_code, fclass,
496 : : library_name, attrs);
497 : 1795005 : DECL_SOURCE_LOCATION (decl) = location;
498 : :
499 : 1795005 : m2block_pushDecl (decl);
500 : 1795005 : return decl;
501 : : }
502 : :
503 : : /* GetBuiltinConst - returns the gcc tree of a builtin constant,
504 : : name. NIL is returned if the constant is unknown. */
505 : :
506 : : tree
507 : 29448 : m2builtins_GetBuiltinConst (char *name)
508 : : {
509 : 29448 : if (strcmp (name, "BITS_PER_UNIT") == 0)
510 : 14724 : return m2decl_BuildIntegerConstant (BITS_PER_UNIT);
511 : 14724 : if (strcmp (name, "BITS_PER_WORD") == 0)
512 : 0 : return m2decl_BuildIntegerConstant (BITS_PER_WORD);
513 : 14724 : if (strcmp (name, "BITS_PER_CHAR") == 0)
514 : 0 : return m2decl_BuildIntegerConstant (CHAR_TYPE_SIZE);
515 : 14724 : if (strcmp (name, "UNITS_PER_WORD") == 0)
516 : 15012 : return m2decl_BuildIntegerConstant (UNITS_PER_WORD);
517 : :
518 : : return NULL_TREE;
519 : : }
520 : :
521 : : /* GetBuiltinConstType - returns the type of a builtin constant,
522 : : name. 0 = unknown constant name 1 = integer 2 = real. */
523 : :
524 : : unsigned int
525 : 0 : m2builtins_GetBuiltinConstType (char *name)
526 : : {
527 : 0 : if (strcmp (name, "BITS_PER_UNIT") == 0)
528 : : return 1;
529 : 0 : if (strcmp (name, "BITS_PER_WORD") == 0)
530 : : return 1;
531 : 0 : if (strcmp (name, "BITS_PER_CHAR") == 0)
532 : : return 1;
533 : 0 : if (strcmp (name, "UNITS_PER_WORD") == 0)
534 : 0 : return 1;
535 : :
536 : : return 0;
537 : : }
538 : :
539 : : /* GetBuiltinTypeInfoType - returns value: 0 is ident is unknown. 1
540 : : if ident is IEC559, LIA1, ISO, IEEE, rounds, underflow, exception,
541 : : extend. 2 if ident is radix, places, exponentmin, exponentmax,
542 : : noofmodes. 3 if ident is large, small. */
543 : :
544 : : unsigned int
545 : 360 : m2builtins_GetBuiltinTypeInfoType (const char *ident)
546 : : {
547 : 360 : int i = 0;
548 : :
549 : 2880 : while (m2_type_info[i].name != NULL)
550 : 2880 : if (strcmp (m2_type_info[i].name, ident) == 0)
551 : 360 : return m2_type_info[i].returnType;
552 : : else
553 : 2520 : i++;
554 : : return 0;
555 : : }
556 : :
557 : : /* GetBuiltinTypeInfo - returns value: NULL_TREE if ident is unknown.
558 : : boolean Tree if ident is IEC559, LIA1, ISO, IEEE, rounds,
559 : : underflow, exception, extend. ZType Tree if ident is radix,
560 : : places, exponentmin, exponentmax, noofmodes.
561 : : RType Tree if ident is large, small. */
562 : :
563 : : tree
564 : 360 : m2builtins_GetBuiltinTypeInfo (location_t location, tree type,
565 : : const char *ident)
566 : : {
567 : 360 : int i = 0;
568 : :
569 : 360 : type = m2tree_skip_type_decl (type);
570 : 3240 : while (m2_type_info[i].name != NULL)
571 : 2880 : if (strcmp (m2_type_info[i].name, ident) == 0)
572 : 360 : return (*m2_type_info[i].functionHandler) (location, type);
573 : : else
574 : 2520 : i++;
575 : : return NULL_TREE;
576 : : }
577 : :
578 : : /* doradix - returns the radix of the floating point, type. */
579 : :
580 : : static tree
581 : 24 : doradix (location_t location ATTRIBUTE_UNUSED, tree type)
582 : : {
583 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
584 : : {
585 : 24 : enum machine_mode mode = TYPE_MODE (type);
586 : 24 : int radix = REAL_MODE_FORMAT (mode)->b;
587 : 24 : return m2decl_BuildIntegerConstant (radix);
588 : : }
589 : : else
590 : : return NULL_TREE;
591 : : }
592 : :
593 : : /* doplaces - returns the whole number value of the number of radix
594 : : places used to store values of the corresponding real number type. */
595 : :
596 : : static tree
597 : 24 : doplaces (location_t location ATTRIBUTE_UNUSED, tree type)
598 : : {
599 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
600 : : {
601 : : /* Taken from c-family/c-cppbuiltin.cc. */
602 : : /* The number of decimal digits, q, such that any floating-point
603 : : number with q decimal digits can be rounded into a
604 : : floating-point number with p radix b digits and back again
605 : : without change to the q decimal digits, p log10 b if b is a
606 : : power of 10 floor((p - 1) log10 b) otherwise. */
607 : 24 : enum machine_mode mode = TYPE_MODE (type);
608 : 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
609 : 24 : const double log10_2 = .30102999566398119521;
610 : 24 : double log10_b = log10_2;
611 : 24 : int digits = (fmt->p - 1) * log10_b;
612 : 24 : return m2decl_BuildIntegerConstant (digits);
613 : : }
614 : : else
615 : : return NULL_TREE;
616 : : }
617 : :
618 : : /* doexponentmin - returns the whole number of the exponent minimum. */
619 : :
620 : : static tree
621 : 24 : doexponentmin (location_t location ATTRIBUTE_UNUSED, tree type)
622 : : {
623 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
624 : : {
625 : 24 : enum machine_mode mode = TYPE_MODE (type);
626 : 24 : int emin = REAL_MODE_FORMAT (mode)->emin;
627 : 24 : return m2decl_BuildIntegerConstant (emin);
628 : : }
629 : : else
630 : : return NULL_TREE;
631 : : }
632 : :
633 : : /* doexponentmax - returns the whole number of the exponent maximum. */
634 : :
635 : : static tree
636 : 24 : doexponentmax (location_t location ATTRIBUTE_UNUSED, tree type)
637 : : {
638 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
639 : : {
640 : 24 : enum machine_mode mode = TYPE_MODE (type);
641 : 24 : int emax = REAL_MODE_FORMAT (mode)->emax;
642 : 24 : return m2decl_BuildIntegerConstant (emax);
643 : : }
644 : : else
645 : : return NULL_TREE;
646 : : }
647 : :
648 : : static tree
649 : 24 : computeLarge (tree type)
650 : : {
651 : 24 : enum machine_mode mode = TYPE_MODE (type);
652 : 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
653 : 24 : REAL_VALUE_TYPE real;
654 : 24 : char buf[128];
655 : :
656 : : /* Shamelessly taken from c-cppbuiltin.cc:builtin_define_float_constants. */
657 : :
658 : : /* Since, for the supported formats, B is always a power of 2, we
659 : : construct the following numbers directly as a hexadecimal constants. */
660 : :
661 : 24 : get_max_float (fmt, buf, sizeof (buf), false);
662 : 24 : real_from_string (&real, buf);
663 : 24 : return build_real (type, real);
664 : : }
665 : :
666 : : /* dolarge - return the largest value of the corresponding real type. */
667 : :
668 : : static tree
669 : 24 : dolarge (location_t location ATTRIBUTE_UNUSED, tree type)
670 : : {
671 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
672 : 24 : return computeLarge (type);
673 : : return NULL_TREE;
674 : : }
675 : :
676 : : static tree
677 : 24 : computeSmall (tree type)
678 : : {
679 : 24 : enum machine_mode mode = TYPE_MODE (type);
680 : 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
681 : 24 : REAL_VALUE_TYPE real;
682 : 24 : char buf[128];
683 : :
684 : : /* The minimum normalized positive floating-point number,
685 : : b**(emin-1). */
686 : :
687 : 24 : sprintf (buf, "0x1p%d", fmt->emin - 1);
688 : 24 : real_from_string (&real, buf);
689 : 24 : return build_real (type, real);
690 : : }
691 : :
692 : : /* dosmall - return the smallest positive value of the corresponding
693 : : real type. */
694 : :
695 : : static tree
696 : 24 : dosmall (location_t location ATTRIBUTE_UNUSED, tree type)
697 : : {
698 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
699 : 24 : return computeSmall (type);
700 : : return NULL_TREE;
701 : : }
702 : :
703 : : /* doiec559 - a boolean value that is true if and only if the
704 : : implementation of the corresponding real number type conforms to
705 : : IEC 559:1989 (also known as IEEE 754:1987) in all regards. */
706 : :
707 : : static tree
708 : 24 : doiec559 (location_t location, tree type)
709 : : {
710 : 24 : if (m2expr_IsTrue (m2expr_BuildEqualTo (location,
711 : : m2decl_BuildIntegerConstant (32),
712 : : m2expr_GetSizeOfInBits (type))))
713 : 0 : return m2type_GetBooleanTrue ();
714 : 24 : if (m2expr_IsTrue (m2expr_BuildEqualTo (location,
715 : : m2decl_BuildIntegerConstant (64),
716 : : m2expr_GetSizeOfInBits (type))))
717 : 0 : return m2type_GetBooleanTrue ();
718 : 24 : return m2type_GetBooleanFalse ();
719 : : }
720 : :
721 : : /* dolia1 - returns TRUE if using ieee (currently always TRUE). */
722 : :
723 : : static tree
724 : 24 : dolia1 (location_t location, tree type)
725 : : {
726 : 48 : return doieee (location, type);
727 : : }
728 : :
729 : : /* doiso - returns TRUE if using ieee (--fixme--). */
730 : :
731 : : static tree
732 : 24 : doiso (location_t location, tree type)
733 : : {
734 : 48 : return doieee (location, type);
735 : : }
736 : :
737 : : /* doieee - returns TRUE if ieee arithmetic is being used. */
738 : :
739 : : static tree
740 : 72 : doieee (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
741 : : {
742 : : /* --fixme-- maybe we should look for the -mno-ieee flag and return this
743 : : result. */
744 : 72 : return m2type_GetBooleanTrue ();
745 : : }
746 : :
747 : : /* dorounds - returns TRUE if and only if each operation produces a
748 : : result that is one of the values of the corresponding real number
749 : : type nearest to the mathematical result. */
750 : :
751 : : static tree
752 : 24 : dorounds (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
753 : : {
754 : 24 : if (FLT_ROUNDS)
755 : 24 : return m2type_GetBooleanTrue ();
756 : : else
757 : : return m2type_GetBooleanFalse ();
758 : : }
759 : :
760 : : /* dogUnderflow - returns TRUE if and only if there are values of the
761 : : corresponding real number type between 0.0 and small. */
762 : :
763 : : static tree
764 : 24 : dogUnderflow (location_t location ATTRIBUTE_UNUSED, tree type)
765 : : {
766 : 24 : if (SCALAR_FLOAT_TYPE_P (type))
767 : : {
768 : 24 : enum machine_mode mode = TYPE_MODE (type);
769 : 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
770 : 24 : if (fmt->has_denorm)
771 : 24 : return m2type_GetBooleanTrue ();
772 : : else
773 : 0 : return m2type_GetBooleanFalse ();
774 : : }
775 : : return NULL_TREE;
776 : : }
777 : :
778 : : /* doexception - */
779 : :
780 : : static tree
781 : 24 : doexception (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
782 : : {
783 : 24 : return m2type_GetBooleanTrue ();
784 : : }
785 : :
786 : : /* doextend - */
787 : :
788 : : static tree
789 : 24 : doextend (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
790 : : {
791 : 24 : return m2type_GetBooleanTrue ();
792 : : }
793 : :
794 : : /* donModes - */
795 : :
796 : : static tree
797 : 24 : donModes (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
798 : : {
799 : 24 : return m2decl_BuildIntegerConstant (1);
800 : : }
801 : :
802 : : /* BuiltinMemCopy - copy n bytes of memory efficiently from address
803 : : src to dest. */
804 : :
805 : : tree
806 : 5859 : m2builtins_BuiltinMemCopy (location_t location, tree dest, tree src, tree n)
807 : : {
808 : 5859 : return DoBuiltinMemCopy (location, dest, src, n);
809 : : }
810 : :
811 : :
812 : : static tree
813 : 0 : DoBuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes)
814 : : {
815 : 0 : tree functype = TREE_TYPE (gm2_memset_node);
816 : 0 : tree funcptr
817 : 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memset_node);
818 : 0 : tree call
819 : 0 : = m2treelib_DoCall3 (location, ptr_type_node, funcptr, ptr, bytevalue, nbytes);
820 : 0 : return call;
821 : : }
822 : :
823 : : /* BuiltinMemSet set copy n bytes of memory efficiently from address
824 : : src to dest. */
825 : :
826 : : tree
827 : 0 : m2builtins_BuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes)
828 : : {
829 : 0 : return DoBuiltinMemSet (location, ptr, bytevalue, nbytes);
830 : : }
831 : :
832 : : /* BuiltInAlloca - given an expression, n, allocate, n, bytes on the
833 : : stack for the life of the current function. */
834 : :
835 : : tree
836 : 4417 : m2builtins_BuiltInAlloca (location_t location, tree n)
837 : : {
838 : 4417 : return DoBuiltinAlloca (location, n);
839 : : }
840 : :
841 : : /* BuiltInIsfinite - return integer 1 if the real expression is
842 : : finite otherwise return integer 0. */
843 : :
844 : : tree
845 : 3152 : m2builtins_BuiltInIsfinite (location_t location, tree expression)
846 : : {
847 : 3152 : return DoBuiltinIsfinite (location, expression);
848 : : }
849 : :
850 : : /* BuiltInIsnan - return integer 1 if the real expression is
851 : : nan otherwise return integer 0. */
852 : :
853 : : tree
854 : 0 : m2builtins_BuiltInIsnan (location_t location, tree expression)
855 : : {
856 : 0 : return DoBuiltinIsnan (location, expression);
857 : : }
858 : :
859 : :
860 : : /* do_target_support_exists returns true if the builting function
861 : : is supported by the target. */
862 : :
863 : : static
864 : : bool
865 : 816 : do_target_support_exists (struct builtin_function_entry *fe)
866 : : {
867 : 816 : tree type = TREE_TYPE (fe->function_node);
868 : :
869 : 816 : switch (fe->function_avail)
870 : : {
871 : : case bf_true:
872 : : return true;
873 : 0 : case bf_false:
874 : 0 : return false;
875 : : case bf_extension_lib:
876 : : return true;
877 : : case bf_default_lib:
878 : : return true;
879 : : case bf_gcc:
880 : : return true;
881 : 48 : case bf_c99:
882 : 48 : return targetm.libc_has_function (function_c99_misc, type);
883 : 392 : case bf_c99_c90res:
884 : 392 : return targetm.libc_has_function (function_c99_misc, type);
885 : : case bf_extension_lib_floatn:
886 : : return true;
887 : 0 : case bf_c99_compl:
888 : 0 : return targetm.libc_has_function (function_c99_math_complex, type);
889 : 0 : default:
890 : 0 : gcc_unreachable ();
891 : : }
892 : : return false;
893 : : }
894 : :
895 : :
896 : : static
897 : : bool
898 : 816 : target_support_exists (struct builtin_function_entry *fe)
899 : : {
900 : : #if defined(DEBUGGING)
901 : : printf ("target_support_exists (%s): ", fe->library_name);
902 : : #endif
903 : 816 : if (do_target_support_exists (fe))
904 : : {
905 : : #if defined(DEBUGGING)
906 : : printf ("yes\n");
907 : : #endif
908 : : return true;
909 : : }
910 : : else
911 : : {
912 : : #if defined(DEBUGGING)
913 : : printf ("no\n");
914 : : #endif
915 : : return false;
916 : : }
917 : : }
918 : :
919 : : /* Return true if name matches the builtin name. */
920 : :
921 : : static
922 : 821602 : bool builtin_function_match (struct builtin_function_entry *fe,
923 : : const char *name)
924 : : {
925 : 821602 : return (strcmp (name, fe->name) == 0)
926 : 821602 : || (strcmp (name, fe->library_name) == 0);
927 : : }
928 : :
929 : : /* Return true if name matches the builtin macro name. */
930 : :
931 : : static
932 : 36288 : bool builtin_macro_match (builtin_macro_definition bmd,
933 : : const char *name)
934 : : {
935 : 36288 : return (strcmp (bmd.name, name) == 0)
936 : 36288 : || (strcmp (bmd.builtinname, name) == 0);
937 : : }
938 : :
939 : :
940 : : /* BuiltinExists - returns TRUE if the builtin function, name, exists
941 : : for this target architecture. */
942 : :
943 : : bool
944 : 17550 : m2builtins_BuiltinExists (char *name)
945 : : {
946 : 17550 : struct builtin_function_entry *fe;
947 : :
948 : 765492 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
949 : 763980 : if (builtin_function_match (fe, name))
950 : : return true;
951 : 1512 : int length = vec_safe_length (builtin_macros);
952 : 31104 : for (int idx = 0; idx < length; idx++)
953 : 31104 : if (builtin_macro_match ((*builtin_macros)[idx], name))
954 : : return true;
955 : : return false;
956 : : }
957 : :
958 : : /* lookup_builtin_function returns a builtin macro. */
959 : :
960 : : static
961 : : tree
962 : 252 : lookup_builtin_macro (location_t location, char *name)
963 : : {
964 : 252 : int length = vec_safe_length (builtin_macros);
965 : 5184 : for (int idx = 0; idx < length; idx++)
966 : 5184 : if (builtin_macro_match ((*builtin_macros)[idx], name))
967 : : {
968 : 252 : tree functype = TREE_TYPE ((*builtin_macros)[idx].function_node);
969 : 252 : tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype),
970 : : (*builtin_macros)[idx].function_node);
971 : 504 : tree call = m2treelib_DoCall (
972 : 252 : location, (*builtin_macros)[idx].return_node,
973 : : funcptr, m2statement_GetParamList ());
974 : 252 : m2statement_SetLastFunction (call);
975 : 252 : m2statement_SetParamList (NULL_TREE);
976 : 252 : if ((*builtin_macros)[idx].return_node == void_type_node)
977 : 0 : m2statement_SetLastFunction (NULL_TREE);
978 : 252 : return call;
979 : : }
980 : : return NULL_TREE;
981 : : }
982 : :
983 : : /* lookup_builtin_function returns a builtin function. */
984 : :
985 : : static
986 : : tree
987 : 1068 : lookup_builtin_function (location_t location, char *name)
988 : : {
989 : 1068 : struct builtin_function_entry *fe;
990 : :
991 : 57874 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
992 : 58438 : if (builtin_function_match (fe, name) && target_support_exists (fe))
993 : : {
994 : 816 : tree functype = TREE_TYPE (fe->function_node);
995 : 816 : tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype),
996 : : fe->function_node);
997 : 816 : tree call = m2treelib_DoCall (
998 : : location, fe->return_node, funcptr, m2statement_GetParamList ());
999 : 816 : m2statement_SetLastFunction (call);
1000 : 816 : m2statement_SetParamList (NULL_TREE);
1001 : 816 : if (fe->return_node == void_type_node)
1002 : 24 : m2statement_SetLastFunction (NULL_TREE);
1003 : 816 : return call;
1004 : : }
1005 : : return NULL_TREE;
1006 : : }
1007 : :
1008 : : /* BuildBuiltinTree - returns a Tree containing the builtin function,
1009 : : name. */
1010 : :
1011 : : tree
1012 : 1068 : m2builtins_BuildBuiltinTree (location_t location, char *name)
1013 : : {
1014 : 1068 : tree call;
1015 : 1068 : m2statement_SetLastFunction (NULL_TREE);
1016 : :
1017 : 1068 : call = lookup_builtin_function (location, name);
1018 : 1068 : if (call == NULL_TREE)
1019 : : {
1020 : 252 : call = lookup_builtin_macro (location, name);
1021 : 252 : if (call == NULL_TREE)
1022 : : {
1023 : 0 : m2statement_SetParamList (NULL_TREE);
1024 : 0 : return m2statement_GetLastFunction ();
1025 : : }
1026 : : }
1027 : : return call;
1028 : : }
1029 : :
1030 : : static tree
1031 : 5859 : DoBuiltinMemCopy (location_t location, tree dest, tree src, tree bytes)
1032 : : {
1033 : 5859 : tree functype = TREE_TYPE (gm2_memcpy_node);
1034 : 5859 : tree rettype = TREE_TYPE (functype);
1035 : 5859 : tree funcptr
1036 : 5859 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memcpy_node);
1037 : 5859 : tree call
1038 : 5859 : = m2treelib_DoCall3 (location, rettype, funcptr, dest, src, bytes);
1039 : 5859 : return call;
1040 : : }
1041 : :
1042 : : static tree
1043 : 4417 : DoBuiltinAlloca (location_t location, tree bytes)
1044 : : {
1045 : 4417 : tree functype = TREE_TYPE (gm2_alloca_node);
1046 : 4417 : tree rettype = TREE_TYPE (functype);
1047 : 4417 : tree funcptr
1048 : 4417 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_alloca_node);
1049 : 4417 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, bytes);
1050 : 4417 : return call;
1051 : : }
1052 : :
1053 : : static tree
1054 : 3152 : DoBuiltinIsfinite (location_t location, tree value)
1055 : : {
1056 : 3152 : tree functype = TREE_TYPE (gm2_isfinite_node);
1057 : 3152 : tree rettype = TREE_TYPE (functype);
1058 : 3152 : tree funcptr
1059 : 3152 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isfinite_node);
1060 : 3152 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, value);
1061 : 3152 : return call;
1062 : : }
1063 : :
1064 : : static tree
1065 : 0 : DoBuiltinIsnan (location_t location, tree value)
1066 : : {
1067 : 0 : tree functype = TREE_TYPE (gm2_isnan_node);
1068 : 0 : tree rettype = TREE_TYPE (functype);
1069 : 0 : tree funcptr
1070 : 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isnan_node);
1071 : 0 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, value);
1072 : 0 : return call;
1073 : : }
1074 : :
1075 : : tree
1076 : 0 : m2builtins_BuiltInHugeVal (location_t location)
1077 : : {
1078 : 0 : tree functype = TREE_TYPE (gm2_huge_val_node);
1079 : 0 : tree rettype = TREE_TYPE (functype);
1080 : 0 : tree funcptr
1081 : 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_val_node);
1082 : 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1083 : 0 : return call;
1084 : : }
1085 : :
1086 : : tree
1087 : 0 : m2builtins_BuiltInHugeValShort (location_t location)
1088 : : {
1089 : 0 : tree functype = TREE_TYPE (gm2_huge_valf_node);
1090 : 0 : tree rettype = TREE_TYPE (functype);
1091 : 0 : tree funcptr
1092 : 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_valf_node);
1093 : 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1094 : 0 : return call;
1095 : : }
1096 : :
1097 : : tree
1098 : 0 : m2builtins_BuiltInHugeValLong (location_t location)
1099 : : {
1100 : 0 : tree functype = TREE_TYPE (gm2_huge_vall_node);
1101 : 0 : tree rettype = TREE_TYPE (functype);
1102 : 0 : tree funcptr
1103 : 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_vall_node);
1104 : 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1105 : 0 : return call;
1106 : : }
1107 : :
1108 : : static void
1109 : 1795005 : create_function_prototype (location_t location,
1110 : : struct builtin_function_entry *fe)
1111 : : {
1112 : 1795005 : tree ftype;
1113 : :
1114 : 1795005 : switch (fe->defn)
1115 : : {
1116 : :
1117 : 15885 : case BT_FN_PTR_SIZE:
1118 : 15885 : ftype = build_function_type (ptr_type_node, sizetype_endlink);
1119 : 15885 : fe->return_node = ptr_type_node;
1120 : 15885 : break;
1121 : :
1122 : 63540 : case BT_FN_STRING_STRING_CONST_STRING_SIZE:
1123 : 63540 : case BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE:
1124 : 63540 : ftype = build_function_type (
1125 : : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node,
1126 : : tree_cons (NULL_TREE, const_ptr_type_node,
1127 : : sizetype_endlink)));
1128 : 63540 : fe->return_node = ptr_type_node;
1129 : 63540 : break;
1130 : 15885 : case BT_FN_FLOAT:
1131 : 15885 : ftype = float_ftype_void;
1132 : 15885 : fe->return_node = float_type_node;
1133 : 15885 : break;
1134 : 15885 : case BT_FN_DOUBLE:
1135 : 15885 : ftype = double_ftype_void;
1136 : 15885 : fe->return_node = double_type_node;
1137 : 15885 : break;
1138 : 15885 : case BT_FN_LONG_DOUBLE:
1139 : 15885 : ftype = ldouble_ftype_void;
1140 : 15885 : fe->return_node = m2type_GetM2LongRealType ();
1141 : 15885 : break;
1142 : 111195 : case BT_FN_FLOAT_FLOAT:
1143 : 111195 : ftype = float_ftype_float;
1144 : 111195 : fe->return_node = float_type_node;
1145 : 111195 : break;
1146 : 111195 : case BT_FN_DOUBLE_DOUBLE:
1147 : 111195 : ftype = double_ftype_double;
1148 : 111195 : fe->return_node = double_type_node;
1149 : 111195 : break;
1150 : 111195 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE:
1151 : 111195 : ftype = ldouble_ftype_ldouble;
1152 : 111195 : fe->return_node = m2type_GetM2LongRealType ();
1153 : 111195 : break;
1154 : 63540 : case BT_FN_STRING_CONST_STRING_INT:
1155 : 63540 : ftype = build_function_type (
1156 : : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1157 : 63540 : fe->return_node = ptr_type_node;
1158 : 63540 : break;
1159 : 15885 : case BT_FN_INT_CONST_PTR_CONST_PTR_SIZE:
1160 : 15885 : ftype = build_function_type (
1161 : : integer_type_node,
1162 : : tree_cons (NULL_TREE, const_ptr_type_node,
1163 : : tree_cons (NULL_TREE, const_ptr_type_node, int_endlink)));
1164 : 15885 : fe->return_node = integer_type_node;
1165 : 15885 : break;
1166 : 15885 : case BT_FN_TRAD_PTR_PTR_INT_SIZE:
1167 : 15885 : ftype = build_function_type (
1168 : : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node,
1169 : : tree_cons (NULL_TREE, integer_type_node,
1170 : : sizetype_endlink)));
1171 : 15885 : fe->return_node = ptr_type_node;
1172 : 15885 : break;
1173 : 31770 : case BT_FN_STRING_STRING_CONST_STRING:
1174 : 31770 : ftype = build_function_type (
1175 : : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, ptr_endlink));
1176 : 31770 : fe->return_node = ptr_type_node;
1177 : 31770 : break;
1178 : 15885 : case BT_FN_INT_CONST_STRING_CONST_STRING:
1179 : 15885 : ftype = build_function_type (
1180 : : integer_type_node,
1181 : : tree_cons (NULL_TREE, const_ptr_type_node, ptr_endlink));
1182 : 15885 : fe->return_node = integer_type_node;
1183 : 15885 : break;
1184 : 15885 : case BT_FN_INT_CONST_STRING_CONST_STRING_SIZE:
1185 : 15885 : ftype = build_function_type (
1186 : : integer_type_node,
1187 : : tree_cons (
1188 : : NULL_TREE, const_ptr_type_node,
1189 : : tree_cons (NULL_TREE, const_ptr_type_node, sizetype_endlink)));
1190 : 15885 : fe->return_node = integer_type_node;
1191 : 15885 : break;
1192 : 15885 : case BT_FN_INT_CONST_STRING:
1193 : 15885 : ftype = build_function_type (integer_type_node, ptr_endlink);
1194 : 15885 : fe->return_node = integer_type_node;
1195 : 15885 : break;
1196 : 31770 : case BT_FN_STRING_CONST_STRING_CONST_STRING:
1197 : 31770 : ftype = build_function_type (
1198 : : ptr_type_node,
1199 : : tree_cons (NULL_TREE, const_ptr_type_node, const_ptr_endlink));
1200 : 31770 : fe->return_node = ptr_type_node;
1201 : 31770 : break;
1202 : 31770 : case BT_FN_SIZE_CONST_STRING_CONST_STRING:
1203 : 31770 : ftype = build_function_type (
1204 : : sizetype,
1205 : : tree_cons (NULL_TREE, const_ptr_type_node, const_ptr_endlink));
1206 : 31770 : fe->return_node = sizetype;
1207 : 31770 : break;
1208 : 31770 : case BT_FN_PTR_UNSIGNED:
1209 : 31770 : ftype = build_function_type (ptr_type_node, unsigned_endlink);
1210 : 31770 : fe->return_node = ptr_type_node;
1211 : 31770 : break;
1212 : 15885 : case BT_FN_VOID_PTR_INT:
1213 : 15885 : ftype = build_function_type (
1214 : : void_type_node, tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1215 : 15885 : fe->return_node = void_type_node;
1216 : 15885 : break;
1217 : 15885 : case BT_FN_INT_PTR:
1218 : 15885 : ftype = build_function_type (integer_type_node, ptr_endlink);
1219 : 15885 : fe->return_node = integer_type_node;
1220 : 15885 : break;
1221 : 31770 : case BT_FN_INT_FLOAT:
1222 : 31770 : ftype = build_function_type (
1223 : : integer_type_node, tree_cons (NULL_TREE, float_type_node, endlink));
1224 : 31770 : fe->return_node = integer_type_node;
1225 : 31770 : break;
1226 : 63540 : case BT_FN_INT_DOUBLE:
1227 : 63540 : ftype = build_function_type (
1228 : : integer_type_node, tree_cons (NULL_TREE, double_type_node, endlink));
1229 : 63540 : fe->return_node = integer_type_node;
1230 : 63540 : break;
1231 : 31770 : case BT_FN_INT_LONG_DOUBLE:
1232 : 31770 : ftype = build_function_type (
1233 : : integer_type_node,
1234 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink));
1235 : 31770 : fe->return_node = integer_type_node;
1236 : 31770 : break;
1237 : 31770 : case BT_FN_FLOAT_FCOMPLEX:
1238 : 31770 : ftype = build_function_type (
1239 : : float_type_node,
1240 : : tree_cons (NULL_TREE, complex_float_type_node, endlink));
1241 : 31770 : fe->return_node = float_type_node;
1242 : 31770 : break;
1243 : 31770 : case BT_FN_DOUBLE_DCOMPLEX:
1244 : 31770 : ftype = build_function_type (
1245 : : double_type_node,
1246 : : tree_cons (NULL_TREE, complex_double_type_node, endlink));
1247 : 31770 : fe->return_node = double_type_node;
1248 : 31770 : break;
1249 : 31770 : case BT_FN_LONG_DOUBLE_LDCOMPLEX:
1250 : 31770 : ftype = build_function_type (
1251 : : m2type_GetM2LongRealType (),
1252 : : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink));
1253 : 31770 : fe->return_node = m2type_GetM2LongRealType ();
1254 : 31770 : break;
1255 : 158850 : case BT_FN_FCOMPLEX_FCOMPLEX:
1256 : 158850 : ftype = build_function_type (
1257 : : complex_float_type_node,
1258 : : tree_cons (NULL_TREE, complex_float_type_node, endlink));
1259 : 158850 : fe->return_node = complex_float_type_node;
1260 : 158850 : break;
1261 : 158850 : case BT_FN_DCOMPLEX_DCOMPLEX:
1262 : 158850 : ftype = build_function_type (
1263 : : complex_double_type_node,
1264 : : tree_cons (NULL_TREE, complex_double_type_node, endlink));
1265 : 158850 : fe->return_node = complex_double_type_node;
1266 : 158850 : break;
1267 : 158850 : case BT_FN_LDCOMPLEX_LDCOMPLEX:
1268 : 158850 : ftype = build_function_type (
1269 : : m2type_GetM2LongComplexType (),
1270 : : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink));
1271 : 158850 : fe->return_node = m2type_GetM2LongComplexType ();
1272 : 158850 : break;
1273 : 15885 : case BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX:
1274 : 15885 : ftype = build_function_type (
1275 : : complex_double_type_node,
1276 : : tree_cons (NULL_TREE, complex_double_type_node,
1277 : : tree_cons (NULL_TREE, double_type_node, endlink)));
1278 : 15885 : fe->return_node = complex_double_type_node;
1279 : 15885 : break;
1280 : 15885 : case BT_FN_FCOMPLEX_FLOAT_FCOMPLEX:
1281 : 15885 : ftype = build_function_type (
1282 : : complex_float_type_node,
1283 : : tree_cons (NULL_TREE, complex_float_type_node,
1284 : : tree_cons (NULL_TREE, float_type_node, endlink)));
1285 : 15885 : fe->return_node = complex_float_type_node;
1286 : 15885 : break;
1287 : 15885 : case BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX:
1288 : 15885 : ftype = build_function_type (
1289 : : m2type_GetM2LongComplexType (),
1290 : : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (),
1291 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1292 : 15885 : fe->return_node = m2type_GetM2LongComplexType ();
1293 : 15885 : break;
1294 : 15885 : case BT_FN_FLOAT_FLOAT_FLOATPTR:
1295 : 15885 : ftype = build_function_type (
1296 : : float_type_node,
1297 : : tree_cons (NULL_TREE, float_type_node,
1298 : : tree_cons (NULL_TREE, floatptr_type_node, endlink)));
1299 : 15885 : fe->return_node = float_type_node;
1300 : 15885 : break;
1301 : 15885 : case BT_FN_DOUBLE_DOUBLE_DOUBLEPTR:
1302 : 15885 : ftype = build_function_type (
1303 : : double_type_node,
1304 : : tree_cons (NULL_TREE, double_type_node,
1305 : : tree_cons (NULL_TREE, doubleptr_type_node, endlink)));
1306 : 15885 : fe->return_node = double_type_node;
1307 : 15885 : break;
1308 : 15885 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR:
1309 : 15885 : ftype = build_function_type (
1310 : : m2type_GetM2LongRealType (),
1311 : : tree_cons (
1312 : : NULL_TREE, m2type_GetM2LongRealType (),
1313 : : tree_cons (NULL_TREE, long_doubleptr_type_node, endlink)));
1314 : 15885 : fe->return_node = m2type_GetM2LongRealType ();
1315 : 15885 : break;
1316 : 15885 : case BT_FN_FLOAT_FLOAT_LONG_DOUBLE:
1317 : 15885 : ftype = build_function_type (
1318 : : float_type_node,
1319 : : tree_cons (NULL_TREE, float_type_node,
1320 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1321 : 15885 : fe->return_node = float_type_node;
1322 : 15885 : break;
1323 : 15885 : case BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE:
1324 : 15885 : ftype = build_function_type (
1325 : : double_type_node,
1326 : : tree_cons (NULL_TREE, double_type_node,
1327 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1328 : 15885 : fe->return_node = double_type_node;
1329 : 15885 : break;
1330 : 47655 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE:
1331 : 47655 : ftype = build_function_type (
1332 : : m2type_GetM2LongRealType (),
1333 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1334 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1335 : 47655 : fe->return_node = m2type_GetM2LongRealType ();
1336 : 47655 : break;
1337 : 15885 : case BT_FN_FLOAT_FLOAT_LONG:
1338 : 15885 : ftype = build_function_type (
1339 : : float_type_node,
1340 : : tree_cons (NULL_TREE, float_type_node,
1341 : : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1342 : 15885 : fe->return_node = float_type_node;
1343 : 15885 : break;
1344 : 15885 : case BT_FN_DOUBLE_DOUBLE_LONG:
1345 : 15885 : ftype = build_function_type (
1346 : : double_type_node,
1347 : : tree_cons (NULL_TREE, double_type_node,
1348 : : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1349 : 15885 : fe->return_node = double_type_node;
1350 : 15885 : break;
1351 : 15885 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG:
1352 : 15885 : ftype = build_function_type (
1353 : : m2type_GetM2LongRealType (),
1354 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1355 : : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1356 : 15885 : fe->return_node = m2type_GetM2LongRealType ();
1357 : 15885 : break;
1358 : 15885 : case BT_FN_FLOAT_FLOAT_INT:
1359 : 15885 : ftype = build_function_type (
1360 : : float_type_node,
1361 : : tree_cons (NULL_TREE, float_type_node,
1362 : : tree_cons (NULL_TREE, integer_type_node, endlink)));
1363 : 15885 : fe->return_node = float_type_node;
1364 : 15885 : break;
1365 : 15885 : case BT_FN_DOUBLE_DOUBLE_INT:
1366 : 15885 : ftype = build_function_type (
1367 : : double_type_node,
1368 : : tree_cons (NULL_TREE, double_type_node,
1369 : : tree_cons (NULL_TREE, integer_type_node, endlink)));
1370 : 15885 : fe->return_node = double_type_node;
1371 : 15885 : break;
1372 : 15885 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT:
1373 : 15885 : ftype = build_function_type (
1374 : : m2type_GetM2LongRealType (),
1375 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1376 : : tree_cons (NULL_TREE, integer_type_node, endlink)));
1377 : 15885 : fe->return_node = m2type_GetM2LongRealType ();
1378 : 15885 : break;
1379 : 31770 : case BT_FN_FLOAT_FLOAT_FLOAT:
1380 : 31770 : ftype = build_function_type (
1381 : : float_type_node,
1382 : : tree_cons (NULL_TREE, float_type_node,
1383 : : tree_cons (NULL_TREE, float_type_node, endlink)));
1384 : 31770 : fe->return_node = float_type_node;
1385 : 31770 : break;
1386 : 31770 : case BT_FN_DOUBLE_DOUBLE_DOUBLE:
1387 : 31770 : ftype = build_function_type (
1388 : : double_type_node,
1389 : : tree_cons (NULL_TREE, double_type_node,
1390 : : tree_cons (NULL_TREE, double_type_node, endlink)));
1391 : 31770 : fe->return_node = double_type_node;
1392 : 31770 : break;
1393 : 0 : default:
1394 : 0 : ERROR ("enum has no case");
1395 : : }
1396 : 1795005 : fe->function_node
1397 : 1795005 : = builtin_function (location, fe->name, ftype, fe->function_code,
1398 : : fe->fclass, fe->library_name, NULL);
1399 : 1795005 : }
1400 : :
1401 : : static tree
1402 : 127080 : find_builtin_tree (const char *name)
1403 : : {
1404 : 127080 : struct builtin_function_entry *fe;
1405 : :
1406 : 5972760 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
1407 : 5972760 : if (strcmp (name, fe->name) == 0)
1408 : 127080 : return fe->function_node;
1409 : :
1410 : 0 : ERROR ("cannot find builtin function");
1411 : : return NULL_TREE;
1412 : : }
1413 : :
1414 : :
1415 : : static void
1416 : 492435 : set_decl_built_in_class (tree decl, built_in_class c)
1417 : : {
1418 : 492435 : FUNCTION_DECL_CHECK (decl)->function_decl.built_in_class = c;
1419 : 492435 : }
1420 : :
1421 : :
1422 : : static void
1423 : 492435 : set_decl_function_code (tree decl, built_in_function f)
1424 : : {
1425 : 492435 : tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
1426 : 492435 : fndecl.function_code = f;
1427 : 492435 : }
1428 : :
1429 : : /* Define a single builtin. */
1430 : :
1431 : : static void
1432 : 492435 : define_builtin (enum built_in_function val, const char *name, tree prototype,
1433 : : const char *libname, int flags)
1434 : : {
1435 : 492435 : tree decl;
1436 : 492435 : builtin_macro_definition bmd;
1437 : :
1438 : 492435 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1439 : : get_identifier (libname), prototype);
1440 : 492435 : DECL_EXTERNAL (decl) = 1;
1441 : 492435 : TREE_PUBLIC (decl) = 1;
1442 : 492435 : SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
1443 : 492435 : m2block_pushDecl (decl);
1444 : 492435 : set_decl_built_in_class (decl, BUILT_IN_NORMAL);
1445 : 492435 : set_decl_function_code (decl, val);
1446 : 492435 : set_call_expr_flags (decl, flags);
1447 : 492435 : set_builtin_decl (val, decl, true);
1448 : 492435 : bmd.name = name;
1449 : 492435 : bmd.builtinname = libname;
1450 : 492435 : bmd.function_node = decl;
1451 : 492435 : bmd.return_node = TREE_TYPE (prototype);
1452 : 492435 : vec_safe_push (builtin_macros, bmd);
1453 : 492435 : }
1454 : :
1455 : : /* Define a math type variant of the builtin function. */
1456 : :
1457 : : static
1458 : : void
1459 : 254160 : define_builtin_ext (enum built_in_function val, const char *name, tree type,
1460 : : const char *libname, int flags, const char *ext)
1461 : : {
1462 : 254160 : char *newname = (char *) xmalloc (strlen (name) + strlen (ext) + 1);
1463 : 254160 : char *newlibname = (char *) xmalloc (strlen (libname) + strlen (ext) + 1);
1464 : 254160 : strcpy (newname, name);
1465 : 254160 : strcat (newname, ext);
1466 : 254160 : strcpy (newlibname, libname);
1467 : 254160 : strcat (newlibname, ext);
1468 : 254160 : define_builtin (val, newname, type, newlibname, flags);
1469 : 254160 : }
1470 : :
1471 : : /* Define all support math type versions of this builtin. */
1472 : :
1473 : : static void
1474 : 127080 : define_builtin_math (enum built_in_function val, const char *name, tree type,
1475 : : const char *libname, int flags)
1476 : : {
1477 : : /* SHORTREAL version. */
1478 : 127080 : define_builtin_ext (val, name, type, libname, flags, "f");
1479 : : /* LONGREAL version. */
1480 : 127080 : define_builtin_ext (val, name, type, libname, flags, "l");
1481 : : /* REAL version. */
1482 : 127080 : define_builtin (val, name, type, libname, flags);
1483 : : /* Perhaps it should declare SYSTEM.def types size floating point
1484 : : versions as well? */
1485 : 127080 : }
1486 : :
1487 : : /* Define gcc specific builtins. */
1488 : :
1489 : : static
1490 : : void
1491 : 15885 : define_builtin_gcc (void)
1492 : : {
1493 : : /* Bit count functions. */
1494 : 15885 : define_builtin (BUILT_IN_CLZ, "clz", builtin_ftype_int_uint,
1495 : : "__builtin_clz", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1496 : 15885 : define_builtin (BUILT_IN_CLZL, "clzl", builtin_ftype_int_ulong,
1497 : : "__builtin_clzl", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1498 : 15885 : define_builtin (BUILT_IN_CLZLL, "clzll", builtin_ftype_int_ulonglong,
1499 : : "__builtin_clzll", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1500 : 15885 : define_builtin (BUILT_IN_CTZ, "ctz", builtin_ftype_int_uint,
1501 : : "__builtin_ctz", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1502 : 15885 : define_builtin (BUILT_IN_CTZL, "ctzl", builtin_ftype_int_ulong,
1503 : : "__builtin_ctzl", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1504 : 15885 : define_builtin (BUILT_IN_CTZLL, "ctzll", builtin_ftype_int_ulonglong,
1505 : : "__builtin_ctzll", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1506 : 15885 : }
1507 : :
1508 : : void
1509 : 15885 : m2builtins_init (location_t location)
1510 : : {
1511 : 15885 : int i;
1512 : :
1513 : 15885 : m2block_pushGlobalScope ();
1514 : 15885 : endlink = void_list_node;
1515 : 15885 : sizetype_endlink = tree_cons (NULL_TREE, sizetype, endlink);
1516 : 15885 : math_endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
1517 : 15885 : int_endlink = tree_cons (NULL_TREE, integer_type_node, NULL_TREE);
1518 : 15885 : ptr_endlink = tree_cons (NULL_TREE, ptr_type_node, NULL_TREE);
1519 : 15885 : const_ptr_endlink = tree_cons (NULL_TREE, const_ptr_type_node, NULL_TREE);
1520 : 15885 : unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, NULL_TREE);
1521 : :
1522 : 15885 : float_ftype_void = build_function_type (float_type_node, math_endlink);
1523 : 15885 : double_ftype_void = build_function_type (double_type_node, math_endlink);
1524 : 15885 : ldouble_ftype_void
1525 : 15885 : = build_function_type (m2type_GetM2LongRealType (), math_endlink);
1526 : :
1527 : 15885 : long_doubleptr_type_node = build_pointer_type (m2type_GetM2LongRealType ());
1528 : 15885 : doubleptr_type_node = build_pointer_type (double_type_node);
1529 : 15885 : floatptr_type_node = build_pointer_type (float_type_node);
1530 : :
1531 : 15885 : float_ftype_float = build_function_type (
1532 : : float_type_node, tree_cons (NULL_TREE, float_type_node, math_endlink));
1533 : :
1534 : 15885 : double_ftype_double = build_function_type (
1535 : : double_type_node, tree_cons (NULL_TREE, double_type_node, math_endlink));
1536 : :
1537 : 15885 : ldouble_ftype_ldouble = build_function_type (
1538 : : m2type_GetM2LongRealType (),
1539 : : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink));
1540 : :
1541 : 15885 : builtin_ftype_int_var = build_function_type (
1542 : : integer_type_node, tree_cons (NULL_TREE, double_type_node, endlink));
1543 : :
1544 : 15885 : builtin_ftype_int_uint = build_function_type (
1545 : : integer_type_node, tree_cons (NULL_TREE, unsigned_type_node, endlink));
1546 : :
1547 : 15885 : builtin_ftype_int_ulong = build_function_type (
1548 : : integer_type_node, tree_cons (NULL_TREE, long_unsigned_type_node, endlink));
1549 : :
1550 : 15885 : builtin_ftype_int_ulonglong = build_function_type (
1551 : : integer_type_node, tree_cons (NULL_TREE, long_long_unsigned_type_node, endlink));
1552 : :
1553 : 1810890 : for (i = 0; list_of_builtins[i].name != NULL; i++)
1554 : 1795005 : create_function_prototype (location, &list_of_builtins[i]);
1555 : :
1556 : 15885 : define_builtin (BUILT_IN_TRAP, "__builtin_trap",
1557 : : build_function_type_list (void_type_node, NULL_TREE),
1558 : : "__builtin_trap", ECF_NOTHROW | ECF_LEAF | ECF_NORETURN);
1559 : 15885 : define_builtin_math (BUILT_IN_ISGREATER, "isgreater", builtin_ftype_int_var,
1560 : : "__builtin_isgreater", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1561 : 15885 : define_builtin_math (BUILT_IN_ISGREATEREQUAL, "isgreaterequal",
1562 : : builtin_ftype_int_var, "__builtin_isgreaterequal",
1563 : : ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1564 : 15885 : define_builtin_math (BUILT_IN_ISLESS, "isless", builtin_ftype_int_var,
1565 : : "__builtin_isless", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1566 : 15885 : define_builtin_math (BUILT_IN_ISLESSEQUAL, "islessequal", builtin_ftype_int_var,
1567 : : "__builtin_islessequal", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1568 : 15885 : define_builtin_math (BUILT_IN_ISLESSGREATER, "islessgreater",
1569 : : builtin_ftype_int_var, "__builtin_islessgreater",
1570 : : ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1571 : 15885 : define_builtin_math (BUILT_IN_ISUNORDERED, "isunordered", builtin_ftype_int_var,
1572 : : "__builtin_isunordered", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1573 : 15885 : define_builtin_math (BUILT_IN_ISNORMAL, "isnormal", builtin_ftype_int_var,
1574 : : "__builtin_isnormal", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1575 : 15885 : define_builtin_math (BUILT_IN_ISINF_SIGN, "isinf_sign", builtin_ftype_int_var,
1576 : : "__builtin_isinf_sign", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1577 : :
1578 : 15885 : define_builtin_gcc ();
1579 : :
1580 : 15885 : gm2_alloca_node = find_builtin_tree ("__builtin_alloca");
1581 : 15885 : gm2_memcpy_node = find_builtin_tree ("__builtin_memcpy");
1582 : 15885 : gm2_memset_node = find_builtin_tree ("__builtin_memset");
1583 : 15885 : gm2_huge_valf_node = find_builtin_tree ("__builtin_huge_valf");
1584 : 15885 : gm2_huge_val_node = find_builtin_tree ("__builtin_huge_val");
1585 : 15885 : gm2_huge_vall_node = find_builtin_tree ("__builtin_huge_vall");
1586 : 15885 : gm2_isfinite_node = find_builtin_tree ("__builtin_isfinite");
1587 : 15885 : gm2_isnan_node = find_builtin_tree ("__builtin_isnan");
1588 : 15885 : m2block_popGlobalScope ();
1589 : 15885 : }
1590 : :
1591 : : #include "gt-m2-m2builtins.h"
1592 : :
1593 : : /* END m2builtins. */
|