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