arm-c.cc revision 1.1 1 1.1 mrg /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
2 1.1 mrg
3 1.1 mrg This file is part of GCC.
4 1.1 mrg
5 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
6 1.1 mrg the terms of the GNU General Public License as published by the Free
7 1.1 mrg Software Foundation; either version 3, or (at your option) any later
8 1.1 mrg version.
9 1.1 mrg
10 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 1.1 mrg for more details.
14 1.1 mrg
15 1.1 mrg You should have received a copy of the GNU General Public License
16 1.1 mrg along with GCC; see the file COPYING3. If not see
17 1.1 mrg <http://www.gnu.org/licenses/>. */
18 1.1 mrg
19 1.1 mrg #define IN_TARGET_CODE 1
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg #include "target.h"
25 1.1 mrg #include "c-family/c-common.h"
26 1.1 mrg #include "memmodel.h"
27 1.1 mrg #include "tm_p.h"
28 1.1 mrg #include "c-family/c-pragma.h"
29 1.1 mrg #include "stringpool.h"
30 1.1 mrg #include "arm-builtins.h"
31 1.1 mrg #include "arm-protos.h"
32 1.1 mrg
33 1.1 mrg tree
34 1.1 mrg arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
35 1.1 mrg {
36 1.1 mrg vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (arglist);
37 1.1 mrg unsigned param_num = params ? params->length() : 0;
38 1.1 mrg unsigned num_args = list_length (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) - 1;
39 1.1 mrg /* Ensure this function has the correct number of arguments.
40 1.1 mrg This won't happen when using the intrinsics defined by the ACLE, since
41 1.1 mrg they're exposed to the user via a wrapper in the arm_cde.h header that has
42 1.1 mrg the correct number of arguments ... hence the compiler would already catch
43 1.1 mrg an incorrect number of arguments there.
44 1.1 mrg
45 1.1 mrg It is still possible to get here if the user tries to call the __bulitin_*
46 1.1 mrg functions directly. We could print some error message in this function,
47 1.1 mrg but instead we leave it to the rest of the code to catch this problem in
48 1.1 mrg the same way that other __builtin_* functions catch it.
49 1.1 mrg
50 1.1 mrg This does mean an odd error message, but it's consistent with the rest of
51 1.1 mrg the builtins. */
52 1.1 mrg if (param_num != num_args)
53 1.1 mrg return NULL_TREE;
54 1.1 mrg
55 1.1 mrg tree to_return = NULL_TREE;
56 1.1 mrg /* Take the functions return type since that's the same type as the arguments
57 1.1 mrg this function needs (the types of the builtin function all come from the
58 1.1 mrg machine mode of the RTL pattern, and they're all the same and calculated
59 1.1 mrg in the same way). */
60 1.1 mrg tree pattern_type = TREE_TYPE (TREE_TYPE (fndecl));
61 1.1 mrg
62 1.1 mrg unsigned i;
63 1.1 mrg /* Hard coding the number of parameters we don't want to cast at the end of
64 1.1 mrg the builtin. This is the easiest approach for the CDE intrinsics, and
65 1.1 mrg introducing a parameter to store in the builtins.def macros seems overkill
66 1.1 mrg when they're only relevant here. */
67 1.1 mrg unsigned end_args = arm_cde_end_args (fndecl);
68 1.1 mrg unsigned cast_param_end = param_num - end_args;
69 1.1 mrg /* For the vcx1q patterns that don't need any casts. */
70 1.1 mrg if (cast_param_end == 1)
71 1.1 mrg return NULL_TREE;
72 1.1 mrg
73 1.1 mrg /* In order to check all arguments rather than complaining on the first
74 1.1 mrg invalid one we record whether *any* arguments are invalid using this
75 1.1 mrg boolean variable. */
76 1.1 mrg bool invalid = false;
77 1.1 mrg for (i = 1; i < cast_param_end; i++)
78 1.1 mrg {
79 1.1 mrg tree this_param = (*params)[i];
80 1.1 mrg if (TREE_CODE (this_param) == ERROR_MARK)
81 1.1 mrg {
82 1.1 mrg invalid = true;
83 1.1 mrg continue;
84 1.1 mrg }
85 1.1 mrg tree param_type = TREE_TYPE (this_param);
86 1.1 mrg
87 1.1 mrg /* Return value is cast to type that second argument originally was.
88 1.1 mrg All non-constant arguments are cast to the return type calculated from
89 1.1 mrg the RTL pattern.
90 1.1 mrg
91 1.1 mrg Set the return type to an unqualified version of the type of the first
92 1.1 mrg parameter. The first parameter since that is how the intrinsics are
93 1.1 mrg defined -- to always return the same type as the first polymorphic
94 1.1 mrg argument. Unqualified version of the type since we don't want passing
95 1.1 mrg a constant parameter to mean that the return value of the builtin is
96 1.1 mrg also constant. */
97 1.1 mrg if (i == 1)
98 1.1 mrg to_return = build_qualified_type (param_type, 0 MEM_STAT_INFO);
99 1.1 mrg
100 1.1 mrg /* The only requirement of these intrinsics on the type of the variable
101 1.1 mrg is that it's 128 bits wide. All other types are valid and we simply
102 1.1 mrg VIEW_CONVERT_EXPR them to the type of the underlying builtin. */
103 1.1 mrg tree type_size = TYPE_SIZE (param_type);
104 1.1 mrg if (! tree_fits_shwi_p (type_size)
105 1.1 mrg || tree_to_shwi (type_size) != 128)
106 1.1 mrg {
107 1.1 mrg error_at (loc,
108 1.1 mrg "argument %u to function %qE is of type %qT which is not "
109 1.1 mrg "known to be 128 bits wide",
110 1.1 mrg i + 1, fndecl, param_type);
111 1.1 mrg invalid = true;
112 1.1 mrg continue;
113 1.1 mrg }
114 1.1 mrg
115 1.1 mrg /* Only convert the argument if we actually need to. */
116 1.1 mrg if (! check_base_type (pattern_type, param_type))
117 1.1 mrg (*params)[i] = build1 (VIEW_CONVERT_EXPR, pattern_type, this_param);
118 1.1 mrg }
119 1.1 mrg if (invalid)
120 1.1 mrg return NULL_TREE;
121 1.1 mrg
122 1.1 mrg /* We know it's safe to call this since this builtin is here to implement an
123 1.1 mrg ACLE function, and those functions are only for C/C++. */
124 1.1 mrg tree call_expr = build_function_call_vec (loc, vNULL, fndecl, params,
125 1.1 mrg NULL, fndecl);
126 1.1 mrg
127 1.1 mrg gcc_assert (to_return != NULL_TREE);
128 1.1 mrg if (! check_base_type (to_return, pattern_type))
129 1.1 mrg return build1 (VIEW_CONVERT_EXPR, to_return, call_expr);
130 1.1 mrg return call_expr;
131 1.1 mrg }
132 1.1 mrg
133 1.1 mrg /* Implement "#pragma GCC arm". */
134 1.1 mrg static void
135 1.1 mrg arm_pragma_arm (cpp_reader *)
136 1.1 mrg {
137 1.1 mrg tree x;
138 1.1 mrg if (pragma_lex (&x) != CPP_STRING)
139 1.1 mrg {
140 1.1 mrg error ("%<#pragma GCC arm%> requires a string parameter");
141 1.1 mrg return;
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg const char *name = TREE_STRING_POINTER (x);
145 1.1 mrg if (strcmp (name, "arm_mve_types.h") == 0)
146 1.1 mrg arm_mve::handle_arm_mve_types_h ();
147 1.1 mrg else
148 1.1 mrg error ("unknown %<#pragma GCC arm%> option %qs", name);
149 1.1 mrg }
150 1.1 mrg
151 1.1 mrg /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. This is currently only
152 1.1 mrg used for the MVE related builtins for the CDE extension.
153 1.1 mrg Here we ensure the type of arguments is such that the size is correct, and
154 1.1 mrg then return a tree that describes the same function call but with the
155 1.1 mrg relevant types cast as necessary. */
156 1.1 mrg tree
157 1.1 mrg arm_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
158 1.1 mrg {
159 1.1 mrg if (arm_describe_resolver (fndecl) == arm_cde_resolver)
160 1.1 mrg return arm_resolve_cde_builtin (loc, fndecl, arglist);
161 1.1 mrg return NULL_TREE;
162 1.1 mrg }
163 1.1 mrg
164 1.1 mrg /* Output C specific EABI object attributes. These cannot be done in
165 1.1 mrg arm.cc because they require information from the C frontend. */
166 1.1 mrg
167 1.1 mrg static void
168 1.1 mrg arm_output_c_attributes (void)
169 1.1 mrg {
170 1.1 mrg int wchar_size = (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT);
171 1.1 mrg arm_emit_eabi_attribute ("Tag_ABI_PCS_wchar_t", 18, wchar_size);
172 1.1 mrg }
173 1.1 mrg
174 1.1 mrg
175 1.1 mrg /* Setup so that common code calls arm_output_c_attributes. */
176 1.1 mrg
177 1.1 mrg void
178 1.1 mrg arm_lang_object_attributes_init (void)
179 1.1 mrg {
180 1.1 mrg arm_lang_output_object_attributes_hook = arm_output_c_attributes;
181 1.1 mrg }
182 1.1 mrg
183 1.1 mrg #define builtin_define(TXT) cpp_define (pfile, TXT)
184 1.1 mrg #define builtin_assert(TXT) cpp_assert (pfile, TXT)
185 1.1 mrg
186 1.1 mrg /* Define or undefine macros based on the current target. If the user does
187 1.1 mrg #pragma GCC target, we need to adjust the macros dynamically. */
188 1.1 mrg
189 1.1 mrg static void
190 1.1 mrg def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p)
191 1.1 mrg {
192 1.1 mrg if (def_p)
193 1.1 mrg cpp_define (pfile, name);
194 1.1 mrg else
195 1.1 mrg cpp_undef (pfile, name);
196 1.1 mrg }
197 1.1 mrg
198 1.1 mrg static void
199 1.1 mrg arm_cpu_builtins (struct cpp_reader* pfile)
200 1.1 mrg {
201 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
202 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
203 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
204 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO);
205 1.1 mrg
206 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_UNALIGNED", unaligned_access);
207 1.1 mrg
208 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_QRDMX", TARGET_NEON_RDMA);
209 1.1 mrg
210 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_CRC32", TARGET_CRC32);
211 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_DOTPROD", TARGET_DOTPROD);
212 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_COMPLEX", TARGET_COMPLEX);
213 1.1 mrg def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
214 1.1 mrg
215 1.1 mrg cpp_undef (pfile, "__ARM_FEATURE_MVE");
216 1.1 mrg if (TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT)
217 1.1 mrg {
218 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_MVE", 3);
219 1.1 mrg }
220 1.1 mrg else if (TARGET_HAVE_MVE)
221 1.1 mrg {
222 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_MVE", 1);
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg cpp_undef (pfile, "__ARM_FEATURE_CMSE");
226 1.1 mrg if (arm_arch8 && !arm_arch_notm)
227 1.1 mrg {
228 1.1 mrg if (arm_arch_cmse && use_cmse)
229 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
230 1.1 mrg else
231 1.1 mrg builtin_define ("__ARM_FEATURE_CMSE");
232 1.1 mrg }
233 1.1 mrg
234 1.1 mrg cpp_undef (pfile, "__ARM_FEATURE_LDREX");
235 1.1 mrg if (TARGET_ARM_FEATURE_LDREX)
236 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
237 1.1 mrg TARGET_ARM_FEATURE_LDREX);
238 1.1 mrg
239 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ",
240 1.1 mrg ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB)
241 1.1 mrg || TARGET_ARM_ARCH_ISA_THUMB >=2));
242 1.1 mrg
243 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_NUMERIC_MAXMIN",
244 1.1 mrg TARGET_ARM_ARCH >= 8 && TARGET_NEON && TARGET_VFP5);
245 1.1 mrg
246 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD);
247 1.1 mrg
248 1.1 mrg builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
249 1.1 mrg flag_short_enums ? 1 : 4);
250 1.1 mrg builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node);
251 1.1 mrg
252 1.1 mrg cpp_undef (pfile, "__ARM_ARCH_PROFILE");
253 1.1 mrg if (TARGET_ARM_ARCH_PROFILE)
254 1.1 mrg builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
255 1.1 mrg TARGET_ARM_ARCH_PROFILE);
256 1.1 mrg
257 1.1 mrg /* Define __arm__ even when in thumb mode, for
258 1.1 mrg consistency with armcc. */
259 1.1 mrg builtin_define ("__arm__");
260 1.1 mrg if (TARGET_ARM_ARCH)
261 1.1 mrg {
262 1.1 mrg cpp_undef (pfile, "__ARM_ARCH");
263 1.1 mrg builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
264 1.1 mrg }
265 1.1 mrg if (arm_arch_notm)
266 1.1 mrg builtin_define ("__ARM_ARCH_ISA_ARM");
267 1.1 mrg builtin_define ("__APCS_32__");
268 1.1 mrg
269 1.1 mrg def_or_undef_macro (pfile, "__GCC_ASM_FLAG_OUTPUTS__", !TARGET_THUMB1);
270 1.1 mrg
271 1.1 mrg def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
272 1.1 mrg def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
273 1.1 mrg if (TARGET_BIG_END)
274 1.1 mrg def_or_undef_macro (pfile, "__THUMBEB__", TARGET_THUMB);
275 1.1 mrg else
276 1.1 mrg def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB);
277 1.1 mrg
278 1.1 mrg cpp_undef (pfile, "__ARM_ARCH_ISA_THUMB");
279 1.1 mrg if (TARGET_ARM_ARCH_ISA_THUMB)
280 1.1 mrg builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB",
281 1.1 mrg TARGET_ARM_ARCH_ISA_THUMB);
282 1.1 mrg
283 1.1 mrg if (TARGET_BIG_END)
284 1.1 mrg {
285 1.1 mrg builtin_define ("__ARMEB__");
286 1.1 mrg builtin_define ("__ARM_BIG_ENDIAN");
287 1.1 mrg }
288 1.1 mrg else
289 1.1 mrg {
290 1.1 mrg builtin_define ("__ARMEL__");
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg if (TARGET_SOFT_FLOAT)
294 1.1 mrg builtin_define ("__SOFTFP__");
295 1.1 mrg
296 1.1 mrg builtin_define ("__VFP_FP__");
297 1.1 mrg
298 1.1 mrg cpp_undef (pfile, "__ARM_FP");
299 1.1 mrg if (TARGET_ARM_FP)
300 1.1 mrg builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
301 1.1 mrg
302 1.1 mrg def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
303 1.1 mrg arm_fp16_format == ARM_FP16_FORMAT_IEEE);
304 1.1 mrg def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
305 1.1 mrg arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
306 1.1 mrg def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
307 1.1 mrg arm_fp16_format != ARM_FP16_FORMAT_NONE);
308 1.1 mrg
309 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
310 1.1 mrg TARGET_VFP_FP16INST);
311 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
312 1.1 mrg TARGET_NEON_FP16INST);
313 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_FML", TARGET_FP16FML);
314 1.1 mrg
315 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
316 1.1 mrg def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
317 1.1 mrg def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
318 1.1 mrg
319 1.1 mrg cpp_undef (pfile, "__ARM_NEON_FP");
320 1.1 mrg if (TARGET_NEON_FP)
321 1.1 mrg builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
322 1.1 mrg
323 1.1 mrg /* Add a define for interworking. Needed when building libgcc.a. */
324 1.1 mrg if (arm_cpp_interwork)
325 1.1 mrg builtin_define ("__THUMB_INTERWORK__");
326 1.1 mrg
327 1.1 mrg builtin_define (arm_arch_name);
328 1.1 mrg if (arm_arch_xscale)
329 1.1 mrg builtin_define ("__XSCALE__");
330 1.1 mrg if (arm_arch_iwmmxt)
331 1.1 mrg {
332 1.1 mrg builtin_define ("__IWMMXT__");
333 1.1 mrg builtin_define ("__ARM_WMMX");
334 1.1 mrg }
335 1.1 mrg if (arm_arch_iwmmxt2)
336 1.1 mrg builtin_define ("__IWMMXT2__");
337 1.1 mrg /* ARMv6KZ was originally identified as the misspelled __ARM_ARCH_6ZK__. To
338 1.1 mrg preserve the existing behavior, the misspelled feature macro must still be
339 1.1 mrg defined. */
340 1.1 mrg if (arm_arch6kz)
341 1.1 mrg builtin_define ("__ARM_ARCH_6ZK__");
342 1.1 mrg if (TARGET_AAPCS_BASED)
343 1.1 mrg {
344 1.1 mrg if (arm_pcs_default == ARM_PCS_AAPCS_VFP)
345 1.1 mrg builtin_define ("__ARM_PCS_VFP");
346 1.1 mrg else if (arm_pcs_default == ARM_PCS_AAPCS)
347 1.1 mrg builtin_define ("__ARM_PCS");
348 1.1 mrg builtin_define ("__ARM_EABI__");
349 1.1 mrg }
350 1.1 mrg
351 1.1 mrg def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
352 1.1 mrg
353 1.1 mrg def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
354 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
355 1.1 mrg
356 1.1 mrg def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
357 1.1 mrg
358 1.1 mrg cpp_undef (pfile, "__ARM_FEATURE_COPROC");
359 1.1 mrg if (TARGET_32BIT && arm_arch4 && !(arm_arch8 && arm_arch_notm))
360 1.1 mrg {
361 1.1 mrg int coproc_level = 0x1;
362 1.1 mrg
363 1.1 mrg if (arm_arch5t)
364 1.1 mrg coproc_level |= 0x2;
365 1.1 mrg if (arm_arch5te)
366 1.1 mrg coproc_level |= 0x4;
367 1.1 mrg if (arm_arch6)
368 1.1 mrg coproc_level |= 0x8;
369 1.1 mrg
370 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_COPROC", coproc_level);
371 1.1 mrg }
372 1.1 mrg
373 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_CDE", TARGET_CDE);
374 1.1 mrg cpp_undef (pfile, "__ARM_FEATURE_CDE_COPROC");
375 1.1 mrg if (TARGET_CDE)
376 1.1 mrg builtin_define_with_int_value ("__ARM_FEATURE_CDE_COPROC",
377 1.1 mrg arm_arch_cde_coproc);
378 1.1 mrg
379 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_MATMUL_INT8", TARGET_I8MM);
380 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC",
381 1.1 mrg TARGET_BF16_FP);
382 1.1 mrg def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC",
383 1.1 mrg TARGET_BF16_SIMD);
384 1.1 mrg def_or_undef_macro (pfile, "__ARM_BF16_FORMAT_ALTERNATIVE",
385 1.1 mrg TARGET_BF16_FP || TARGET_BF16_SIMD);
386 1.1 mrg }
387 1.1 mrg
388 1.1 mrg void
389 1.1 mrg arm_cpu_cpp_builtins (struct cpp_reader * pfile)
390 1.1 mrg {
391 1.1 mrg builtin_assert ("cpu=arm");
392 1.1 mrg builtin_assert ("machine=arm");
393 1.1 mrg
394 1.1 mrg arm_cpu_builtins (pfile);
395 1.1 mrg }
396 1.1 mrg
397 1.1 mrg /* Hook to validate the current #pragma GCC target and set the arch custom
398 1.1 mrg mode state. If ARGS is NULL, then POP_TARGET is used to reset
399 1.1 mrg the options. */
400 1.1 mrg
401 1.1 mrg static bool
402 1.1 mrg arm_pragma_target_parse (tree args, tree pop_target)
403 1.1 mrg {
404 1.1 mrg tree prev_tree = target_option_current_node;
405 1.1 mrg tree cur_tree;
406 1.1 mrg struct cl_target_option *prev_opt;
407 1.1 mrg struct cl_target_option *cur_opt;
408 1.1 mrg
409 1.1 mrg if (! args)
410 1.1 mrg {
411 1.1 mrg cur_tree = ((pop_target) ? pop_target : target_option_default_node);
412 1.1 mrg cl_target_option_restore (&global_options, &global_options_set,
413 1.1 mrg TREE_TARGET_OPTION (cur_tree));
414 1.1 mrg }
415 1.1 mrg else
416 1.1 mrg {
417 1.1 mrg cur_tree = arm_valid_target_attribute_tree (args, &global_options,
418 1.1 mrg &global_options_set);
419 1.1 mrg if (cur_tree == NULL_TREE)
420 1.1 mrg {
421 1.1 mrg cl_target_option_restore (&global_options, &global_options_set,
422 1.1 mrg TREE_TARGET_OPTION (prev_tree));
423 1.1 mrg return false;
424 1.1 mrg }
425 1.1 mrg
426 1.1 mrg /* handle_pragma_pop_options and handle_pragma_reset_options will set
427 1.1 mrg target_option_current_node, but not handle_pragma_target. */
428 1.1 mrg target_option_current_node = cur_tree;
429 1.1 mrg arm_configure_build_target (&arm_active_target,
430 1.1 mrg TREE_TARGET_OPTION (cur_tree), false);
431 1.1 mrg arm_option_reconfigure_globals ();
432 1.1 mrg }
433 1.1 mrg
434 1.1 mrg /* Update macros if target_node changes. The global state will be restored
435 1.1 mrg by arm_set_current_function. */
436 1.1 mrg prev_opt = TREE_TARGET_OPTION (prev_tree);
437 1.1 mrg cur_opt = TREE_TARGET_OPTION (cur_tree);
438 1.1 mrg
439 1.1 mrg gcc_assert (prev_opt);
440 1.1 mrg gcc_assert (cur_opt);
441 1.1 mrg
442 1.1 mrg if (cur_opt != prev_opt)
443 1.1 mrg {
444 1.1 mrg /* For the definitions, ensure all newly defined macros are considered
445 1.1 mrg as used for -Wunused-macros. There is no point warning about the
446 1.1 mrg compiler predefined macros. */
447 1.1 mrg cpp_options *cpp_opts = cpp_get_options (parse_in);
448 1.1 mrg unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
449 1.1 mrg
450 1.1 mrg cpp_opts->warn_unused_macros = 0;
451 1.1 mrg
452 1.1 mrg /* Update macros. */
453 1.1 mrg gcc_assert (cur_opt->x_target_flags == target_flags);
454 1.1 mrg
455 1.1 mrg /* Don't warn for macros that have context sensitive values depending on
456 1.1 mrg other attributes.
457 1.1 mrg See warn_of_redefinition, reset after cpp_create_definition. */
458 1.1 mrg tree acond_macro = get_identifier ("__ARM_NEON_FP");
459 1.1 mrg C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL ;
460 1.1 mrg
461 1.1 mrg acond_macro = get_identifier ("__ARM_FP");
462 1.1 mrg C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
463 1.1 mrg
464 1.1 mrg acond_macro = get_identifier ("__ARM_FEATURE_LDREX");
465 1.1 mrg C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
466 1.1 mrg
467 1.1 mrg cpp_force_token_locations (parse_in, BUILTINS_LOCATION);
468 1.1 mrg arm_cpu_builtins (parse_in);
469 1.1 mrg cpp_stop_forcing_token_locations (parse_in);
470 1.1 mrg
471 1.1 mrg cpp_opts->warn_unused_macros = saved_warn_unused_macros;
472 1.1 mrg
473 1.1 mrg /* Make sure that target_reinit is called for next function, since
474 1.1 mrg TREE_TARGET_OPTION might change with the #pragma even if there is
475 1.1 mrg no target attribute attached to the function. */
476 1.1 mrg arm_reset_previous_fndecl ();
477 1.1 mrg
478 1.1 mrg /* If going to the default mode, we restore the initial states.
479 1.1 mrg if cur_tree is a new target, states will be saved/restored on a per
480 1.1 mrg function basis in arm_set_current_function. */
481 1.1 mrg if (cur_tree == target_option_default_node)
482 1.1 mrg save_restore_target_globals (cur_tree);
483 1.1 mrg }
484 1.1 mrg
485 1.1 mrg return true;
486 1.1 mrg }
487 1.1 mrg
488 1.1 mrg /* Register target pragmas. We need to add the hook for parsing #pragma GCC
489 1.1 mrg option here rather than in arm.cc since it will pull in various preprocessor
490 1.1 mrg functions, and those are not present in languages like fortran without a
491 1.1 mrg preprocessor. */
492 1.1 mrg
493 1.1 mrg void
494 1.1 mrg arm_register_target_pragmas (void)
495 1.1 mrg {
496 1.1 mrg /* Update pragma hook to allow parsing #pragma GCC target. */
497 1.1 mrg targetm.target_option.pragma_parse = arm_pragma_target_parse;
498 1.1 mrg targetm.resolve_overloaded_builtin = arm_resolve_overloaded_builtin;
499 1.1 mrg
500 1.1 mrg c_register_pragma ("GCC", "arm", arm_pragma_arm);
501 1.1 mrg
502 1.1 mrg #ifdef REGISTER_SUBTARGET_PRAGMAS
503 1.1 mrg REGISTER_SUBTARGET_PRAGMAS ();
504 1.1 mrg #endif
505 1.1 mrg }
506