]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm-c.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arm / arm-c.c
CommitLineData
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
32tree
33arm_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. */
137tree
138arm_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
148static void
149arm_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
158void
159arm_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
170static void
c8b6aa7c 171def_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
179static void
180arm_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
369void
370arm_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
382static bool
383arm_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
472void
473arm_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}