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