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