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 :
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_strncpy_node;
422 : static GTY (()) tree gm2_isfinite_node;
423 : static GTY (()) tree gm2_isnan_node;
424 : static GTY (()) tree gm2_huge_valf_node;
425 : static GTY (()) tree gm2_huge_val_node;
426 : static GTY (()) tree gm2_huge_vall_node;
427 : static GTY (()) tree long_doubleptr_type_node;
428 : static GTY (()) tree doubleptr_type_node;
429 : static GTY (()) tree floatptr_type_node;
430 : static GTY (()) tree builtin_ftype_int_var;
431 : static GTY (()) tree builtin_ftype_int_uint;
432 : static GTY (()) tree builtin_ftype_int_ulong;
433 : static GTY (()) tree builtin_ftype_int_ulonglong;
434 : static GTY (()) vec<builtin_macro_definition, va_gc> *builtin_macros;
435 :
436 : /* Prototypes for locally defined functions. */
437 : static tree DoBuiltinAlloca (location_t location, tree n);
438 : static tree DoBuiltinMemCopy (location_t location, tree dest, tree src,
439 : tree n);
440 : static tree DoBuiltinIsfinite (location_t location, tree value);
441 : static tree DoBuiltinIsnan (location_t location, tree value);
442 : static void create_function_prototype (location_t location,
443 : struct builtin_function_entry *fe);
444 : static tree doradix (location_t location, tree type);
445 : static tree doplaces (location_t location, tree type);
446 : static tree doexponentmin (location_t location, tree type);
447 : static tree doexponentmax (location_t location, tree type);
448 : static tree dolarge (location_t location, tree type);
449 : static tree dosmall (location_t location, tree type);
450 : static tree doiec559 (location_t location, tree type);
451 : static tree dolia1 (location_t location, tree type);
452 : static tree doiso (location_t location, tree type);
453 : static tree doieee (location_t location, tree type);
454 : static tree dorounds (location_t location, tree type);
455 : static tree dogUnderflow (location_t location, tree type);
456 : static tree doexception (location_t location, tree type);
457 : static tree doextend (location_t location, tree type);
458 : static tree donModes (location_t location, tree type);
459 : /* Prototypes finish here. */
460 :
461 : #define m2builtins_c
462 : #include "m2builtins.h"
463 :
464 : static struct builtin_type_info m2_type_info[] = {
465 : { "radix", 2, doradix },
466 : { "places", 2, doplaces },
467 : { "expoMin", 2, doexponentmin },
468 : { "expoMax", 2, doexponentmax },
469 : { "large", 3, dolarge },
470 : { "small", 3, dosmall },
471 : { "IEC559", 1, doiec559 },
472 : { "LIA1", 1, dolia1 },
473 : { "ISO", 1, doiso },
474 : { "IEEE", 1, doieee },
475 : { "rounds", 1, dorounds },
476 : { "gUnderflow", 1, dogUnderflow },
477 : { "exception", 1, doexception },
478 : { "extend", 1, doextend },
479 : { "nModes", 2, donModes },
480 : { NULL, 0, NULL },
481 : };
482 :
483 : /* Return a definition for a builtin function named NAME and whose
484 : data type is TYPE. TYPE should be a function type with argument
485 : types. FUNCTION_CODE tells later passes how to compile calls to this
486 : function. See tree.h for its possible values.
487 :
488 : If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, the
489 : name to be called if we can't opencode the function. */
490 :
491 : tree
492 1689576 : builtin_function (location_t location, const char *name, tree type,
493 : int function_code, enum built_in_class fclass,
494 : const char *library_name, tree attrs)
495 : {
496 1689576 : tree decl = add_builtin_function (name, type, function_code, fclass,
497 : library_name, attrs);
498 1689576 : DECL_SOURCE_LOCATION (decl) = location;
499 :
500 1689576 : m2block_pushDecl (decl);
501 1689576 : return decl;
502 : }
503 :
504 : /* GetBuiltinConst - returns the gcc tree of a builtin constant,
505 : name. NIL is returned if the constant is unknown. */
506 :
507 : tree
508 27520 : m2builtins_GetBuiltinConst (char *name)
509 : {
510 27520 : if (strcmp (name, "BITS_PER_UNIT") == 0)
511 13760 : return m2decl_BuildIntegerConstant (BITS_PER_UNIT);
512 13760 : if (strcmp (name, "BITS_PER_WORD") == 0)
513 0 : return m2decl_BuildIntegerConstant (BITS_PER_WORD);
514 13760 : if (strcmp (name, "BITS_PER_CHAR") == 0)
515 0 : return m2decl_BuildIntegerConstant (CHAR_TYPE_SIZE);
516 13760 : if (strcmp (name, "UNITS_PER_WORD") == 0)
517 14066 : return m2decl_BuildIntegerConstant (UNITS_PER_WORD);
518 :
519 : return NULL_TREE;
520 : }
521 :
522 : /* GetBuiltinConstType - returns the type of a builtin constant,
523 : name. 0 = unknown constant name 1 = integer 2 = real. */
524 :
525 : unsigned int
526 0 : m2builtins_GetBuiltinConstType (char *name)
527 : {
528 0 : if (strcmp (name, "BITS_PER_UNIT") == 0)
529 : return 1;
530 0 : if (strcmp (name, "BITS_PER_WORD") == 0)
531 : return 1;
532 0 : if (strcmp (name, "BITS_PER_CHAR") == 0)
533 : return 1;
534 0 : if (strcmp (name, "UNITS_PER_WORD") == 0)
535 0 : return 1;
536 :
537 : return 0;
538 : }
539 :
540 : /* GetBuiltinTypeInfoType - returns value: 0 is ident is unknown. 1
541 : if ident is IEC559, LIA1, ISO, IEEE, rounds, underflow, exception,
542 : extend. 2 if ident is radix, places, exponentmin, exponentmax,
543 : noofmodes. 3 if ident is large, small. */
544 :
545 : unsigned int
546 360 : m2builtins_GetBuiltinTypeInfoType (const char *ident)
547 : {
548 360 : int i = 0;
549 :
550 2880 : while (m2_type_info[i].name != NULL)
551 2880 : if (strcmp (m2_type_info[i].name, ident) == 0)
552 360 : return m2_type_info[i].returnType;
553 : else
554 2520 : i++;
555 : return 0;
556 : }
557 :
558 : /* GetBuiltinTypeInfo - returns value: NULL_TREE if ident is unknown.
559 : boolean Tree if ident is IEC559, LIA1, ISO, IEEE, rounds,
560 : underflow, exception, extend. ZType Tree if ident is radix,
561 : places, exponentmin, exponentmax, noofmodes.
562 : RType Tree if ident is large, small. */
563 :
564 : tree
565 360 : m2builtins_GetBuiltinTypeInfo (location_t location, tree type,
566 : const char *ident)
567 : {
568 360 : int i = 0;
569 :
570 360 : type = m2tree_skip_type_decl (type);
571 3240 : while (m2_type_info[i].name != NULL)
572 2880 : if (strcmp (m2_type_info[i].name, ident) == 0)
573 360 : return (*m2_type_info[i].functionHandler) (location, type);
574 : else
575 2520 : i++;
576 : return NULL_TREE;
577 : }
578 :
579 : /* doradix - returns the radix of the floating point, type. */
580 :
581 : static tree
582 24 : doradix (location_t location ATTRIBUTE_UNUSED, tree type)
583 : {
584 24 : if (SCALAR_FLOAT_TYPE_P (type))
585 : {
586 24 : enum machine_mode mode = TYPE_MODE (type);
587 24 : int radix = REAL_MODE_FORMAT (mode)->b;
588 24 : return m2decl_BuildIntegerConstant (radix);
589 : }
590 : else
591 : return NULL_TREE;
592 : }
593 :
594 : /* doplaces - returns the whole number value of the number of radix
595 : places used to store values of the corresponding real number type. */
596 :
597 : static tree
598 24 : doplaces (location_t location ATTRIBUTE_UNUSED, tree type)
599 : {
600 24 : if (SCALAR_FLOAT_TYPE_P (type))
601 : {
602 : /* Taken from c-family/c-cppbuiltin.cc. */
603 : /* The number of decimal digits, q, such that any floating-point
604 : number with q decimal digits can be rounded into a
605 : floating-point number with p radix b digits and back again
606 : without change to the q decimal digits, p log10 b if b is a
607 : power of 10 floor((p - 1) log10 b) otherwise. */
608 24 : enum machine_mode mode = TYPE_MODE (type);
609 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
610 24 : const double log10_2 = .30102999566398119521;
611 24 : double log10_b = log10_2;
612 24 : int digits = (fmt->p - 1) * log10_b;
613 24 : return m2decl_BuildIntegerConstant (digits);
614 : }
615 : else
616 : return NULL_TREE;
617 : }
618 :
619 : /* doexponentmin - returns the whole number of the exponent minimum. */
620 :
621 : static tree
622 24 : doexponentmin (location_t location ATTRIBUTE_UNUSED, tree type)
623 : {
624 24 : if (SCALAR_FLOAT_TYPE_P (type))
625 : {
626 24 : enum machine_mode mode = TYPE_MODE (type);
627 24 : int emin = REAL_MODE_FORMAT (mode)->emin;
628 24 : return m2decl_BuildIntegerConstant (emin);
629 : }
630 : else
631 : return NULL_TREE;
632 : }
633 :
634 : /* doexponentmax - returns the whole number of the exponent maximum. */
635 :
636 : static tree
637 24 : doexponentmax (location_t location ATTRIBUTE_UNUSED, tree type)
638 : {
639 24 : if (SCALAR_FLOAT_TYPE_P (type))
640 : {
641 24 : enum machine_mode mode = TYPE_MODE (type);
642 24 : int emax = REAL_MODE_FORMAT (mode)->emax;
643 24 : return m2decl_BuildIntegerConstant (emax);
644 : }
645 : else
646 : return NULL_TREE;
647 : }
648 :
649 : static tree
650 24 : computeLarge (tree type)
651 : {
652 24 : enum machine_mode mode = TYPE_MODE (type);
653 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
654 24 : REAL_VALUE_TYPE real;
655 24 : char buf[128];
656 :
657 : /* Shamelessly taken from c-cppbuiltin.cc:builtin_define_float_constants. */
658 :
659 : /* Since, for the supported formats, B is always a power of 2, we
660 : construct the following numbers directly as a hexadecimal constants. */
661 :
662 24 : get_max_float (fmt, buf, sizeof (buf), false);
663 24 : real_from_string (&real, buf);
664 24 : return build_real (type, real);
665 : }
666 :
667 : /* dolarge - return the largest value of the corresponding real type. */
668 :
669 : static tree
670 24 : dolarge (location_t location ATTRIBUTE_UNUSED, tree type)
671 : {
672 24 : if (SCALAR_FLOAT_TYPE_P (type))
673 24 : return computeLarge (type);
674 : return NULL_TREE;
675 : }
676 :
677 : static tree
678 24 : computeSmall (tree type)
679 : {
680 24 : enum machine_mode mode = TYPE_MODE (type);
681 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
682 24 : REAL_VALUE_TYPE real;
683 24 : char buf[128];
684 :
685 : /* The minimum normalized positive floating-point number,
686 : b**(emin-1). */
687 :
688 24 : sprintf (buf, "0x1p%d", fmt->emin - 1);
689 24 : real_from_string (&real, buf);
690 24 : return build_real (type, real);
691 : }
692 :
693 : /* dosmall - return the smallest positive value of the corresponding
694 : real type. */
695 :
696 : static tree
697 24 : dosmall (location_t location ATTRIBUTE_UNUSED, tree type)
698 : {
699 24 : if (SCALAR_FLOAT_TYPE_P (type))
700 24 : return computeSmall (type);
701 : return NULL_TREE;
702 : }
703 :
704 : /* doiec559 - a boolean value that is true if and only if the
705 : implementation of the corresponding real number type conforms to
706 : IEC 559:1989 (also known as IEEE 754:1987) in all regards. */
707 :
708 : static tree
709 24 : doiec559 (location_t location, tree type)
710 : {
711 24 : if (m2expr_IsTrue (m2expr_BuildEqualTo (location,
712 : m2decl_BuildIntegerConstant (32),
713 : m2expr_GetSizeOfInBits (type))))
714 0 : return m2type_GetBooleanTrue ();
715 24 : if (m2expr_IsTrue (m2expr_BuildEqualTo (location,
716 : m2decl_BuildIntegerConstant (64),
717 : m2expr_GetSizeOfInBits (type))))
718 0 : return m2type_GetBooleanTrue ();
719 24 : return m2type_GetBooleanFalse ();
720 : }
721 :
722 : /* dolia1 - returns TRUE if using ieee (currently always TRUE). */
723 :
724 : static tree
725 24 : dolia1 (location_t location, tree type)
726 : {
727 48 : return doieee (location, type);
728 : }
729 :
730 : /* doiso - returns TRUE if using ieee (--fixme--). */
731 :
732 : static tree
733 24 : doiso (location_t location, tree type)
734 : {
735 48 : return doieee (location, type);
736 : }
737 :
738 : /* doieee - returns TRUE if ieee arithmetic is being used. */
739 :
740 : static tree
741 72 : doieee (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
742 : {
743 : /* --fixme-- maybe we should look for the -mno-ieee flag and return this
744 : result. */
745 72 : return m2type_GetBooleanTrue ();
746 : }
747 :
748 : /* dorounds - returns TRUE if and only if each operation produces a
749 : result that is one of the values of the corresponding real number
750 : type nearest to the mathematical result. */
751 :
752 : static tree
753 24 : dorounds (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
754 : {
755 24 : if (FLT_ROUNDS)
756 24 : return m2type_GetBooleanTrue ();
757 : else
758 : return m2type_GetBooleanFalse ();
759 : }
760 :
761 : /* dogUnderflow - returns TRUE if and only if there are values of the
762 : corresponding real number type between 0.0 and small. */
763 :
764 : static tree
765 24 : dogUnderflow (location_t location ATTRIBUTE_UNUSED, tree type)
766 : {
767 24 : if (SCALAR_FLOAT_TYPE_P (type))
768 : {
769 24 : enum machine_mode mode = TYPE_MODE (type);
770 24 : const struct real_format *fmt = REAL_MODE_FORMAT (mode);
771 24 : if (fmt->has_denorm)
772 24 : return m2type_GetBooleanTrue ();
773 : else
774 0 : return m2type_GetBooleanFalse ();
775 : }
776 : return NULL_TREE;
777 : }
778 :
779 : /* doexception - */
780 :
781 : static tree
782 24 : doexception (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
783 : {
784 24 : return m2type_GetBooleanTrue ();
785 : }
786 :
787 : /* doextend - */
788 :
789 : static tree
790 24 : doextend (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
791 : {
792 24 : return m2type_GetBooleanTrue ();
793 : }
794 :
795 : /* donModes - */
796 :
797 : static tree
798 24 : donModes (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED)
799 : {
800 24 : return m2decl_BuildIntegerConstant (1);
801 : }
802 :
803 : /* BuiltinMemCopy - copy n bytes of memory efficiently from address
804 : src to dest. */
805 :
806 : tree
807 7810 : m2builtins_BuiltinMemCopy (location_t location, tree dest, tree src, tree n)
808 : {
809 7810 : return DoBuiltinMemCopy (location, dest, src, n);
810 : }
811 :
812 :
813 : static tree
814 0 : DoBuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes)
815 : {
816 0 : tree functype = TREE_TYPE (gm2_memset_node);
817 0 : tree funcptr
818 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memset_node);
819 0 : tree call
820 0 : = m2treelib_DoCall3 (location, ptr_type_node, funcptr, ptr, bytevalue, nbytes);
821 0 : return call;
822 : }
823 :
824 : /* BuiltinMemSet set copy n bytes of memory efficiently from address
825 : src to dest. */
826 :
827 : tree
828 0 : m2builtins_BuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes)
829 : {
830 0 : return DoBuiltinMemSet (location, ptr, bytevalue, nbytes);
831 : }
832 :
833 : /* BuiltInAlloca - given an expression, n, allocate, n, bytes on the
834 : stack for the life of the current function. */
835 :
836 : tree
837 5468 : m2builtins_BuiltInAlloca (location_t location, tree n)
838 : {
839 5468 : return DoBuiltinAlloca (location, n);
840 : }
841 :
842 : /* BuiltInIsfinite - return integer 1 if the real expression is
843 : finite otherwise return integer 0. */
844 :
845 : tree
846 4616 : m2builtins_BuiltInIsfinite (location_t location, tree expression)
847 : {
848 4616 : return DoBuiltinIsfinite (location, expression);
849 : }
850 :
851 : /* BuiltInIsnan - return integer 1 if the real expression is
852 : nan otherwise return integer 0. */
853 :
854 : tree
855 0 : m2builtins_BuiltInIsnan (location_t location, tree expression)
856 : {
857 0 : return DoBuiltinIsnan (location, expression);
858 : }
859 :
860 :
861 : /* do_target_support_exists returns true if the builting function
862 : is supported by the target. */
863 :
864 : static
865 : bool
866 900 : do_target_support_exists (struct builtin_function_entry *fe)
867 : {
868 900 : tree type = TREE_TYPE (fe->function_node);
869 :
870 900 : switch (fe->function_avail)
871 : {
872 : case bf_true:
873 : return true;
874 0 : case bf_false:
875 0 : return false;
876 : case bf_extension_lib:
877 : return true;
878 : case bf_default_lib:
879 : return true;
880 : case bf_gcc:
881 : return true;
882 48 : case bf_c99:
883 48 : return targetm.libc_has_function (function_c99_misc, type);
884 392 : case bf_c99_c90res:
885 392 : return targetm.libc_has_function (function_c99_misc, type);
886 : case bf_extension_lib_floatn:
887 : return true;
888 0 : case bf_c99_compl:
889 0 : return targetm.libc_has_function (function_c99_math_complex, type);
890 0 : default:
891 0 : gcc_unreachable ();
892 : }
893 : return false;
894 : }
895 :
896 :
897 : static
898 : bool
899 900 : target_support_exists (struct builtin_function_entry *fe)
900 : {
901 : #if defined(DEBUGGING)
902 : printf ("target_support_exists (%s): ", fe->library_name);
903 : #endif
904 900 : if (do_target_support_exists (fe))
905 : {
906 : #if defined(DEBUGGING)
907 : printf ("yes\n");
908 : #endif
909 : return true;
910 : }
911 : else
912 : {
913 : #if defined(DEBUGGING)
914 : printf ("no\n");
915 : #endif
916 : return false;
917 : }
918 : }
919 :
920 : /* Return true if name matches the builtin name. */
921 :
922 : static
923 947190 : bool builtin_function_match (struct builtin_function_entry *fe,
924 : const char *name)
925 : {
926 947190 : return (strcmp (name, fe->name) == 0)
927 947190 : || (strcmp (name, fe->library_name) == 0);
928 : }
929 :
930 : /* Return true if name matches the builtin macro name. */
931 :
932 : static
933 36288 : bool builtin_macro_match (builtin_macro_definition bmd,
934 : const char *name)
935 : {
936 36288 : return (strcmp (bmd.name, name) == 0)
937 36288 : || (strcmp (bmd.builtinname, name) == 0);
938 : }
939 :
940 :
941 : /* BuiltinExists - returns TRUE if the builtin function, name, exists
942 : for this target architecture. */
943 :
944 : bool
945 20314 : m2builtins_BuiltinExists (char *name)
946 : {
947 20314 : struct builtin_function_entry *fe;
948 :
949 888280 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
950 886768 : if (builtin_function_match (fe, name))
951 : return true;
952 1512 : int length = vec_safe_length (builtin_macros);
953 31104 : for (int idx = 0; idx < length; idx++)
954 31104 : if (builtin_macro_match ((*builtin_macros)[idx], name))
955 : return true;
956 : return false;
957 : }
958 :
959 : /* lookup_builtin_function returns a builtin macro. */
960 :
961 : static
962 : tree
963 252 : lookup_builtin_macro (location_t location, char *name)
964 : {
965 252 : int length = vec_safe_length (builtin_macros);
966 5184 : for (int idx = 0; idx < length; idx++)
967 5184 : if (builtin_macro_match ((*builtin_macros)[idx], name))
968 : {
969 252 : tree functype = TREE_TYPE ((*builtin_macros)[idx].function_node);
970 252 : tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype),
971 : (*builtin_macros)[idx].function_node);
972 504 : tree call = m2treelib_DoCall (
973 252 : location, (*builtin_macros)[idx].return_node,
974 : funcptr, m2statement_GetParamList ());
975 252 : m2statement_SetLastFunction (call);
976 252 : m2statement_SetParamList (NULL_TREE);
977 252 : if ((*builtin_macros)[idx].return_node == void_type_node)
978 0 : m2statement_SetLastFunction (NULL_TREE);
979 252 : return call;
980 : }
981 : return NULL_TREE;
982 : }
983 :
984 : /* lookup_builtin_function returns a builtin function. */
985 :
986 : static
987 : tree
988 1152 : lookup_builtin_function (location_t location, char *name)
989 : {
990 1152 : struct builtin_function_entry *fe;
991 :
992 60674 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
993 61322 : if (builtin_function_match (fe, name) && target_support_exists (fe))
994 : {
995 900 : tree functype = TREE_TYPE (fe->function_node);
996 900 : tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype),
997 : fe->function_node);
998 900 : tree call = m2treelib_DoCall (
999 : location, fe->return_node, funcptr, m2statement_GetParamList ());
1000 900 : m2statement_SetLastFunction (call);
1001 900 : m2statement_SetParamList (NULL_TREE);
1002 900 : if (fe->return_node == void_type_node)
1003 24 : m2statement_SetLastFunction (NULL_TREE);
1004 900 : return call;
1005 : }
1006 : return NULL_TREE;
1007 : }
1008 :
1009 : /* BuildBuiltinTree - returns a Tree containing the builtin function,
1010 : name. */
1011 :
1012 : tree
1013 1152 : m2builtins_BuildBuiltinTree (location_t location, char *name)
1014 : {
1015 1152 : tree call;
1016 1152 : m2statement_SetLastFunction (NULL_TREE);
1017 :
1018 1152 : call = lookup_builtin_function (location, name);
1019 1152 : if (call == NULL_TREE)
1020 : {
1021 252 : call = lookup_builtin_macro (location, name);
1022 252 : if (call == NULL_TREE)
1023 : {
1024 0 : m2statement_SetParamList (NULL_TREE);
1025 0 : return m2statement_GetLastFunction ();
1026 : }
1027 : }
1028 : return call;
1029 : }
1030 :
1031 : static tree
1032 7810 : DoBuiltinMemCopy (location_t location, tree dest, tree src, tree bytes)
1033 : {
1034 7810 : tree functype = TREE_TYPE (gm2_memcpy_node);
1035 7810 : tree rettype = TREE_TYPE (functype);
1036 7810 : tree funcptr
1037 7810 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memcpy_node);
1038 7810 : tree call
1039 7810 : = m2treelib_DoCall3 (location, rettype, funcptr, dest, src, bytes);
1040 7810 : return call;
1041 : }
1042 :
1043 : static tree
1044 84 : DoBuiltinStrNCopy (location_t location, tree dest, tree src, tree bytes)
1045 : {
1046 84 : tree functype = TREE_TYPE (gm2_strncpy_node);
1047 84 : tree rettype = TREE_TYPE (functype);
1048 84 : tree funcptr
1049 84 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_strncpy_node);
1050 84 : tree call
1051 84 : = m2treelib_DoCall3 (location, rettype, funcptr, dest, src, bytes);
1052 84 : return call;
1053 : }
1054 :
1055 : static tree
1056 5468 : DoBuiltinAlloca (location_t location, tree bytes)
1057 : {
1058 5468 : tree functype = TREE_TYPE (gm2_alloca_node);
1059 5468 : tree rettype = TREE_TYPE (functype);
1060 5468 : tree funcptr
1061 5468 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_alloca_node);
1062 5468 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, bytes);
1063 5468 : return call;
1064 : }
1065 :
1066 : static tree
1067 4616 : DoBuiltinIsfinite (location_t location, tree value)
1068 : {
1069 4616 : tree functype = TREE_TYPE (gm2_isfinite_node);
1070 4616 : tree rettype = TREE_TYPE (functype);
1071 4616 : tree funcptr
1072 4616 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isfinite_node);
1073 4616 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, value);
1074 4616 : return call;
1075 : }
1076 :
1077 : static tree
1078 0 : DoBuiltinIsnan (location_t location, tree value)
1079 : {
1080 0 : tree functype = TREE_TYPE (gm2_isnan_node);
1081 0 : tree rettype = TREE_TYPE (functype);
1082 0 : tree funcptr
1083 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_isnan_node);
1084 0 : tree call = m2treelib_DoCall1 (location, rettype, funcptr, value);
1085 0 : return call;
1086 : }
1087 :
1088 : tree
1089 0 : m2builtins_BuiltInHugeVal (location_t location)
1090 : {
1091 0 : tree functype = TREE_TYPE (gm2_huge_val_node);
1092 0 : tree rettype = TREE_TYPE (functype);
1093 0 : tree funcptr
1094 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_val_node);
1095 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1096 0 : return call;
1097 : }
1098 :
1099 : tree
1100 0 : m2builtins_BuiltInHugeValShort (location_t location)
1101 : {
1102 0 : tree functype = TREE_TYPE (gm2_huge_valf_node);
1103 0 : tree rettype = TREE_TYPE (functype);
1104 0 : tree funcptr
1105 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_valf_node);
1106 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1107 0 : return call;
1108 : }
1109 :
1110 : tree
1111 0 : m2builtins_BuiltInHugeValLong (location_t location)
1112 : {
1113 0 : tree functype = TREE_TYPE (gm2_huge_vall_node);
1114 0 : tree rettype = TREE_TYPE (functype);
1115 0 : tree funcptr
1116 0 : = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_huge_vall_node);
1117 0 : tree call = m2treelib_DoCall0 (location, rettype, funcptr);
1118 0 : return call;
1119 : }
1120 :
1121 : /* BuiltinStrNCopy copy at most n chars from address src to dest. */
1122 :
1123 : tree
1124 84 : m2builtins_BuiltinStrNCopy (location_t location, tree dest, tree src, tree n)
1125 : {
1126 84 : return DoBuiltinStrNCopy (location, dest, src, n);
1127 : }
1128 :
1129 : static void
1130 1689576 : create_function_prototype (location_t location,
1131 : struct builtin_function_entry *fe)
1132 : {
1133 1689576 : tree ftype;
1134 :
1135 1689576 : switch (fe->defn)
1136 : {
1137 :
1138 14952 : case BT_FN_PTR_SIZE:
1139 14952 : ftype = build_function_type (ptr_type_node, sizetype_endlink);
1140 14952 : fe->return_node = ptr_type_node;
1141 14952 : break;
1142 :
1143 59808 : case BT_FN_STRING_STRING_CONST_STRING_SIZE:
1144 59808 : case BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE:
1145 59808 : ftype = build_function_type (
1146 : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node,
1147 : tree_cons (NULL_TREE, const_ptr_type_node,
1148 : sizetype_endlink)));
1149 59808 : fe->return_node = ptr_type_node;
1150 59808 : break;
1151 14952 : case BT_FN_FLOAT:
1152 14952 : ftype = float_ftype_void;
1153 14952 : fe->return_node = float_type_node;
1154 14952 : break;
1155 14952 : case BT_FN_DOUBLE:
1156 14952 : ftype = double_ftype_void;
1157 14952 : fe->return_node = double_type_node;
1158 14952 : break;
1159 14952 : case BT_FN_LONG_DOUBLE:
1160 14952 : ftype = ldouble_ftype_void;
1161 14952 : fe->return_node = m2type_GetM2LongRealType ();
1162 14952 : break;
1163 104664 : case BT_FN_FLOAT_FLOAT:
1164 104664 : ftype = float_ftype_float;
1165 104664 : fe->return_node = float_type_node;
1166 104664 : break;
1167 104664 : case BT_FN_DOUBLE_DOUBLE:
1168 104664 : ftype = double_ftype_double;
1169 104664 : fe->return_node = double_type_node;
1170 104664 : break;
1171 104664 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE:
1172 104664 : ftype = ldouble_ftype_ldouble;
1173 104664 : fe->return_node = m2type_GetM2LongRealType ();
1174 104664 : break;
1175 59808 : case BT_FN_STRING_CONST_STRING_INT:
1176 59808 : ftype = build_function_type (
1177 : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1178 59808 : fe->return_node = ptr_type_node;
1179 59808 : break;
1180 14952 : case BT_FN_INT_CONST_PTR_CONST_PTR_SIZE:
1181 14952 : ftype = build_function_type (
1182 : integer_type_node,
1183 : tree_cons (NULL_TREE, const_ptr_type_node,
1184 : tree_cons (NULL_TREE, const_ptr_type_node, int_endlink)));
1185 14952 : fe->return_node = integer_type_node;
1186 14952 : break;
1187 14952 : case BT_FN_TRAD_PTR_PTR_INT_SIZE:
1188 14952 : ftype = build_function_type (
1189 : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node,
1190 : tree_cons (NULL_TREE, integer_type_node,
1191 : sizetype_endlink)));
1192 14952 : fe->return_node = ptr_type_node;
1193 14952 : break;
1194 29904 : case BT_FN_STRING_STRING_CONST_STRING:
1195 29904 : ftype = build_function_type (
1196 : ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, ptr_endlink));
1197 29904 : fe->return_node = ptr_type_node;
1198 29904 : break;
1199 14952 : case BT_FN_INT_CONST_STRING_CONST_STRING:
1200 14952 : ftype = build_function_type (
1201 : integer_type_node,
1202 : tree_cons (NULL_TREE, const_ptr_type_node, ptr_endlink));
1203 14952 : fe->return_node = integer_type_node;
1204 14952 : break;
1205 14952 : case BT_FN_INT_CONST_STRING_CONST_STRING_SIZE:
1206 14952 : ftype = build_function_type (
1207 : integer_type_node,
1208 : tree_cons (
1209 : NULL_TREE, const_ptr_type_node,
1210 : tree_cons (NULL_TREE, const_ptr_type_node, sizetype_endlink)));
1211 14952 : fe->return_node = integer_type_node;
1212 14952 : break;
1213 14952 : case BT_FN_INT_CONST_STRING:
1214 14952 : ftype = build_function_type (integer_type_node, ptr_endlink);
1215 14952 : fe->return_node = integer_type_node;
1216 14952 : break;
1217 29904 : case BT_FN_STRING_CONST_STRING_CONST_STRING:
1218 29904 : ftype = build_function_type (
1219 : ptr_type_node,
1220 : tree_cons (NULL_TREE, const_ptr_type_node, const_ptr_endlink));
1221 29904 : fe->return_node = ptr_type_node;
1222 29904 : break;
1223 29904 : case BT_FN_SIZE_CONST_STRING_CONST_STRING:
1224 29904 : ftype = build_function_type (
1225 : sizetype,
1226 : tree_cons (NULL_TREE, const_ptr_type_node, const_ptr_endlink));
1227 29904 : fe->return_node = sizetype;
1228 29904 : break;
1229 29904 : case BT_FN_PTR_UNSIGNED:
1230 29904 : ftype = build_function_type (ptr_type_node, unsigned_endlink);
1231 29904 : fe->return_node = ptr_type_node;
1232 29904 : break;
1233 14952 : case BT_FN_VOID_PTR_INT:
1234 14952 : ftype = build_function_type (
1235 : void_type_node, tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1236 14952 : fe->return_node = void_type_node;
1237 14952 : break;
1238 14952 : case BT_FN_INT_PTR:
1239 14952 : ftype = build_function_type (integer_type_node, ptr_endlink);
1240 14952 : fe->return_node = integer_type_node;
1241 14952 : break;
1242 29904 : case BT_FN_INT_FLOAT:
1243 29904 : ftype = build_function_type (
1244 : integer_type_node, tree_cons (NULL_TREE, float_type_node, endlink));
1245 29904 : fe->return_node = integer_type_node;
1246 29904 : break;
1247 59808 : case BT_FN_INT_DOUBLE:
1248 59808 : ftype = build_function_type (
1249 : integer_type_node, tree_cons (NULL_TREE, double_type_node, endlink));
1250 59808 : fe->return_node = integer_type_node;
1251 59808 : break;
1252 29904 : case BT_FN_INT_LONG_DOUBLE:
1253 29904 : ftype = build_function_type (
1254 : integer_type_node,
1255 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink));
1256 29904 : fe->return_node = integer_type_node;
1257 29904 : break;
1258 29904 : case BT_FN_FLOAT_FCOMPLEX:
1259 29904 : ftype = build_function_type (
1260 : float_type_node,
1261 : tree_cons (NULL_TREE, complex_float_type_node, endlink));
1262 29904 : fe->return_node = float_type_node;
1263 29904 : break;
1264 29904 : case BT_FN_DOUBLE_DCOMPLEX:
1265 29904 : ftype = build_function_type (
1266 : double_type_node,
1267 : tree_cons (NULL_TREE, complex_double_type_node, endlink));
1268 29904 : fe->return_node = double_type_node;
1269 29904 : break;
1270 29904 : case BT_FN_LONG_DOUBLE_LDCOMPLEX:
1271 29904 : ftype = build_function_type (
1272 : m2type_GetM2LongRealType (),
1273 : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink));
1274 29904 : fe->return_node = m2type_GetM2LongRealType ();
1275 29904 : break;
1276 149520 : case BT_FN_FCOMPLEX_FCOMPLEX:
1277 149520 : ftype = build_function_type (
1278 : complex_float_type_node,
1279 : tree_cons (NULL_TREE, complex_float_type_node, endlink));
1280 149520 : fe->return_node = complex_float_type_node;
1281 149520 : break;
1282 149520 : case BT_FN_DCOMPLEX_DCOMPLEX:
1283 149520 : ftype = build_function_type (
1284 : complex_double_type_node,
1285 : tree_cons (NULL_TREE, complex_double_type_node, endlink));
1286 149520 : fe->return_node = complex_double_type_node;
1287 149520 : break;
1288 149520 : case BT_FN_LDCOMPLEX_LDCOMPLEX:
1289 149520 : ftype = build_function_type (
1290 : m2type_GetM2LongComplexType (),
1291 : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink));
1292 149520 : fe->return_node = m2type_GetM2LongComplexType ();
1293 149520 : break;
1294 14952 : case BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX:
1295 14952 : ftype = build_function_type (
1296 : complex_double_type_node,
1297 : tree_cons (NULL_TREE, complex_double_type_node,
1298 : tree_cons (NULL_TREE, double_type_node, endlink)));
1299 14952 : fe->return_node = complex_double_type_node;
1300 14952 : break;
1301 14952 : case BT_FN_FCOMPLEX_FLOAT_FCOMPLEX:
1302 14952 : ftype = build_function_type (
1303 : complex_float_type_node,
1304 : tree_cons (NULL_TREE, complex_float_type_node,
1305 : tree_cons (NULL_TREE, float_type_node, endlink)));
1306 14952 : fe->return_node = complex_float_type_node;
1307 14952 : break;
1308 14952 : case BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX:
1309 14952 : ftype = build_function_type (
1310 : m2type_GetM2LongComplexType (),
1311 : tree_cons (NULL_TREE, m2type_GetM2LongComplexType (),
1312 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1313 14952 : fe->return_node = m2type_GetM2LongComplexType ();
1314 14952 : break;
1315 14952 : case BT_FN_FLOAT_FLOAT_FLOATPTR:
1316 14952 : ftype = build_function_type (
1317 : float_type_node,
1318 : tree_cons (NULL_TREE, float_type_node,
1319 : tree_cons (NULL_TREE, floatptr_type_node, endlink)));
1320 14952 : fe->return_node = float_type_node;
1321 14952 : break;
1322 14952 : case BT_FN_DOUBLE_DOUBLE_DOUBLEPTR:
1323 14952 : ftype = build_function_type (
1324 : double_type_node,
1325 : tree_cons (NULL_TREE, double_type_node,
1326 : tree_cons (NULL_TREE, doubleptr_type_node, endlink)));
1327 14952 : fe->return_node = double_type_node;
1328 14952 : break;
1329 14952 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR:
1330 14952 : ftype = build_function_type (
1331 : m2type_GetM2LongRealType (),
1332 : tree_cons (
1333 : NULL_TREE, m2type_GetM2LongRealType (),
1334 : tree_cons (NULL_TREE, long_doubleptr_type_node, endlink)));
1335 14952 : fe->return_node = m2type_GetM2LongRealType ();
1336 14952 : break;
1337 14952 : case BT_FN_FLOAT_FLOAT_LONG_DOUBLE:
1338 14952 : ftype = build_function_type (
1339 : float_type_node,
1340 : tree_cons (NULL_TREE, float_type_node,
1341 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1342 14952 : fe->return_node = float_type_node;
1343 14952 : break;
1344 14952 : case BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE:
1345 14952 : ftype = build_function_type (
1346 : double_type_node,
1347 : tree_cons (NULL_TREE, double_type_node,
1348 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1349 14952 : fe->return_node = double_type_node;
1350 14952 : break;
1351 44856 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE:
1352 44856 : ftype = build_function_type (
1353 : m2type_GetM2LongRealType (),
1354 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1355 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)));
1356 44856 : fe->return_node = m2type_GetM2LongRealType ();
1357 44856 : break;
1358 14952 : case BT_FN_FLOAT_FLOAT_LONG:
1359 14952 : ftype = build_function_type (
1360 : float_type_node,
1361 : tree_cons (NULL_TREE, float_type_node,
1362 : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1363 14952 : fe->return_node = float_type_node;
1364 14952 : break;
1365 14952 : case BT_FN_DOUBLE_DOUBLE_LONG:
1366 14952 : ftype = build_function_type (
1367 : double_type_node,
1368 : tree_cons (NULL_TREE, double_type_node,
1369 : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1370 14952 : fe->return_node = double_type_node;
1371 14952 : break;
1372 14952 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG:
1373 14952 : ftype = build_function_type (
1374 : m2type_GetM2LongRealType (),
1375 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1376 : tree_cons (NULL_TREE, long_integer_type_node, endlink)));
1377 14952 : fe->return_node = m2type_GetM2LongRealType ();
1378 14952 : break;
1379 14952 : case BT_FN_FLOAT_FLOAT_INT:
1380 14952 : ftype = build_function_type (
1381 : float_type_node,
1382 : tree_cons (NULL_TREE, float_type_node,
1383 : tree_cons (NULL_TREE, integer_type_node, endlink)));
1384 14952 : fe->return_node = float_type_node;
1385 14952 : break;
1386 14952 : case BT_FN_DOUBLE_DOUBLE_INT:
1387 14952 : ftype = build_function_type (
1388 : double_type_node,
1389 : tree_cons (NULL_TREE, double_type_node,
1390 : tree_cons (NULL_TREE, integer_type_node, endlink)));
1391 14952 : fe->return_node = double_type_node;
1392 14952 : break;
1393 14952 : case BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT:
1394 14952 : ftype = build_function_type (
1395 : m2type_GetM2LongRealType (),
1396 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (),
1397 : tree_cons (NULL_TREE, integer_type_node, endlink)));
1398 14952 : fe->return_node = m2type_GetM2LongRealType ();
1399 14952 : break;
1400 29904 : case BT_FN_FLOAT_FLOAT_FLOAT:
1401 29904 : ftype = build_function_type (
1402 : float_type_node,
1403 : tree_cons (NULL_TREE, float_type_node,
1404 : tree_cons (NULL_TREE, float_type_node, endlink)));
1405 29904 : fe->return_node = float_type_node;
1406 29904 : break;
1407 29904 : case BT_FN_DOUBLE_DOUBLE_DOUBLE:
1408 29904 : ftype = build_function_type (
1409 : double_type_node,
1410 : tree_cons (NULL_TREE, double_type_node,
1411 : tree_cons (NULL_TREE, double_type_node, endlink)));
1412 29904 : fe->return_node = double_type_node;
1413 29904 : break;
1414 0 : default:
1415 0 : ERROR ("enum has no case");
1416 : }
1417 1689576 : fe->function_node
1418 1689576 : = builtin_function (location, fe->name, ftype, fe->function_code,
1419 : fe->fclass, fe->library_name, NULL);
1420 1689576 : }
1421 :
1422 : static tree
1423 134568 : find_builtin_tree (const char *name)
1424 : {
1425 134568 : struct builtin_function_entry *fe;
1426 :
1427 7117152 : for (fe = &list_of_builtins[0]; fe->name != NULL; fe++)
1428 7117152 : if (strcmp (name, fe->name) == 0)
1429 134568 : return fe->function_node;
1430 :
1431 0 : ERROR ("cannot find builtin function");
1432 : return NULL_TREE;
1433 : }
1434 :
1435 :
1436 : static void
1437 463512 : set_decl_built_in_class (tree decl, built_in_class c)
1438 : {
1439 463512 : FUNCTION_DECL_CHECK (decl)->function_decl.built_in_class = c;
1440 463512 : }
1441 :
1442 :
1443 : static void
1444 463512 : set_decl_function_code (tree decl, built_in_function f)
1445 : {
1446 463512 : tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
1447 463512 : fndecl.function_code = f;
1448 463512 : }
1449 :
1450 : /* Define a single builtin. */
1451 :
1452 : static void
1453 463512 : define_builtin (enum built_in_function val, const char *name, tree prototype,
1454 : const char *libname, int flags)
1455 : {
1456 463512 : tree decl;
1457 463512 : builtin_macro_definition bmd;
1458 :
1459 463512 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1460 : get_identifier (libname), prototype);
1461 463512 : DECL_EXTERNAL (decl) = 1;
1462 463512 : TREE_PUBLIC (decl) = 1;
1463 463512 : SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
1464 463512 : m2block_pushDecl (decl);
1465 463512 : set_decl_built_in_class (decl, BUILT_IN_NORMAL);
1466 463512 : set_decl_function_code (decl, val);
1467 463512 : set_call_expr_flags (decl, flags);
1468 463512 : set_builtin_decl (val, decl, true);
1469 463512 : bmd.name = name;
1470 463512 : bmd.builtinname = libname;
1471 463512 : bmd.function_node = decl;
1472 463512 : bmd.return_node = TREE_TYPE (prototype);
1473 463512 : vec_safe_push (builtin_macros, bmd);
1474 463512 : }
1475 :
1476 : /* Define a math type variant of the builtin function. */
1477 :
1478 : static
1479 : void
1480 239232 : define_builtin_ext (enum built_in_function val, const char *name, tree type,
1481 : const char *libname, int flags, const char *ext)
1482 : {
1483 239232 : char *newname = (char *) xmalloc (strlen (name) + strlen (ext) + 1);
1484 239232 : char *newlibname = (char *) xmalloc (strlen (libname) + strlen (ext) + 1);
1485 239232 : strcpy (newname, name);
1486 239232 : strcat (newname, ext);
1487 239232 : strcpy (newlibname, libname);
1488 239232 : strcat (newlibname, ext);
1489 239232 : define_builtin (val, newname, type, newlibname, flags);
1490 239232 : }
1491 :
1492 : /* Define all support math type versions of this builtin. */
1493 :
1494 : static void
1495 119616 : define_builtin_math (enum built_in_function val, const char *name, tree type,
1496 : const char *libname, int flags)
1497 : {
1498 : /* SHORTREAL version. */
1499 119616 : define_builtin_ext (val, name, type, libname, flags, "f");
1500 : /* LONGREAL version. */
1501 119616 : define_builtin_ext (val, name, type, libname, flags, "l");
1502 : /* REAL version. */
1503 119616 : define_builtin (val, name, type, libname, flags);
1504 : /* Perhaps it should declare SYSTEM.def types size floating point
1505 : versions as well? */
1506 119616 : }
1507 :
1508 : /* Define gcc specific builtins. */
1509 :
1510 : static
1511 : void
1512 14952 : define_builtin_gcc (void)
1513 : {
1514 : /* Bit count functions. */
1515 14952 : define_builtin (BUILT_IN_CLZ, "clz", builtin_ftype_int_uint,
1516 : "__builtin_clz", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1517 14952 : define_builtin (BUILT_IN_CLZL, "clzl", builtin_ftype_int_ulong,
1518 : "__builtin_clzl", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1519 14952 : define_builtin (BUILT_IN_CLZLL, "clzll", builtin_ftype_int_ulonglong,
1520 : "__builtin_clzll", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1521 14952 : define_builtin (BUILT_IN_CTZ, "ctz", builtin_ftype_int_uint,
1522 : "__builtin_ctz", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1523 14952 : define_builtin (BUILT_IN_CTZL, "ctzl", builtin_ftype_int_ulong,
1524 : "__builtin_ctzl", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1525 14952 : define_builtin (BUILT_IN_CTZLL, "ctzll", builtin_ftype_int_ulonglong,
1526 : "__builtin_ctzll", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1527 14952 : }
1528 :
1529 : void
1530 14952 : m2builtins_init (location_t location)
1531 : {
1532 14952 : int i;
1533 :
1534 14952 : m2block_pushGlobalScope ();
1535 14952 : endlink = void_list_node;
1536 14952 : sizetype_endlink = tree_cons (NULL_TREE, sizetype, endlink);
1537 14952 : math_endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
1538 14952 : int_endlink = tree_cons (NULL_TREE, integer_type_node, NULL_TREE);
1539 14952 : ptr_endlink = tree_cons (NULL_TREE, ptr_type_node, NULL_TREE);
1540 14952 : const_ptr_endlink = tree_cons (NULL_TREE, const_ptr_type_node, NULL_TREE);
1541 14952 : unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, NULL_TREE);
1542 :
1543 14952 : float_ftype_void = build_function_type (float_type_node, math_endlink);
1544 14952 : double_ftype_void = build_function_type (double_type_node, math_endlink);
1545 14952 : ldouble_ftype_void
1546 14952 : = build_function_type (m2type_GetM2LongRealType (), math_endlink);
1547 :
1548 14952 : long_doubleptr_type_node = build_pointer_type (m2type_GetM2LongRealType ());
1549 14952 : doubleptr_type_node = build_pointer_type (double_type_node);
1550 14952 : floatptr_type_node = build_pointer_type (float_type_node);
1551 :
1552 14952 : float_ftype_float = build_function_type (
1553 : float_type_node, tree_cons (NULL_TREE, float_type_node, math_endlink));
1554 :
1555 14952 : double_ftype_double = build_function_type (
1556 : double_type_node, tree_cons (NULL_TREE, double_type_node, math_endlink));
1557 :
1558 14952 : ldouble_ftype_ldouble = build_function_type (
1559 : m2type_GetM2LongRealType (),
1560 : tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink));
1561 :
1562 14952 : builtin_ftype_int_var = build_function_type (
1563 : integer_type_node, tree_cons (NULL_TREE, double_type_node, endlink));
1564 :
1565 14952 : builtin_ftype_int_uint = build_function_type (
1566 : integer_type_node, tree_cons (NULL_TREE, unsigned_type_node, endlink));
1567 :
1568 14952 : builtin_ftype_int_ulong = build_function_type (
1569 : integer_type_node, tree_cons (NULL_TREE, long_unsigned_type_node, endlink));
1570 :
1571 14952 : builtin_ftype_int_ulonglong = build_function_type (
1572 : integer_type_node, tree_cons (NULL_TREE, long_long_unsigned_type_node, endlink));
1573 :
1574 1704528 : for (i = 0; list_of_builtins[i].name != NULL; i++)
1575 1689576 : create_function_prototype (location, &list_of_builtins[i]);
1576 :
1577 14952 : define_builtin (BUILT_IN_TRAP, "__builtin_trap",
1578 : build_function_type_list (void_type_node, NULL_TREE),
1579 : "__builtin_trap", ECF_NOTHROW | ECF_LEAF | ECF_NORETURN);
1580 14952 : define_builtin_math (BUILT_IN_ISGREATER, "isgreater", builtin_ftype_int_var,
1581 : "__builtin_isgreater", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1582 14952 : define_builtin_math (BUILT_IN_ISGREATEREQUAL, "isgreaterequal",
1583 : builtin_ftype_int_var, "__builtin_isgreaterequal",
1584 : ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1585 14952 : define_builtin_math (BUILT_IN_ISLESS, "isless", builtin_ftype_int_var,
1586 : "__builtin_isless", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1587 14952 : define_builtin_math (BUILT_IN_ISLESSEQUAL, "islessequal", builtin_ftype_int_var,
1588 : "__builtin_islessequal", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1589 14952 : define_builtin_math (BUILT_IN_ISLESSGREATER, "islessgreater",
1590 : builtin_ftype_int_var, "__builtin_islessgreater",
1591 : ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1592 14952 : define_builtin_math (BUILT_IN_ISUNORDERED, "isunordered", builtin_ftype_int_var,
1593 : "__builtin_isunordered", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1594 14952 : define_builtin_math (BUILT_IN_ISNORMAL, "isnormal", builtin_ftype_int_var,
1595 : "__builtin_isnormal", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1596 14952 : define_builtin_math (BUILT_IN_ISINF_SIGN, "isinf_sign", builtin_ftype_int_var,
1597 : "__builtin_isinf_sign", ECF_CONST | ECF_NOTHROW | ECF_LEAF);
1598 :
1599 14952 : define_builtin_gcc ();
1600 :
1601 14952 : gm2_alloca_node = find_builtin_tree ("__builtin_alloca");
1602 14952 : gm2_memcpy_node = find_builtin_tree ("__builtin_memcpy");
1603 14952 : gm2_memset_node = find_builtin_tree ("__builtin_memset");
1604 14952 : gm2_strncpy_node = find_builtin_tree ("__builtin_strncpy");
1605 14952 : gm2_huge_valf_node = find_builtin_tree ("__builtin_huge_valf");
1606 14952 : gm2_huge_val_node = find_builtin_tree ("__builtin_huge_val");
1607 14952 : gm2_huge_vall_node = find_builtin_tree ("__builtin_huge_vall");
1608 14952 : gm2_isfinite_node = find_builtin_tree ("__builtin_isfinite");
1609 14952 : gm2_isnan_node = find_builtin_tree ("__builtin_isnan");
1610 14952 : m2block_popGlobalScope ();
1611 14952 : }
1612 :
1613 : #include "gt-m2-m2builtins.h"
1614 :
1615 : /* END m2builtins. */
|