]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/aarch64/aarch64-c.c
x86: Check leal/addl gcc.target/i386/amxtile-3.c for x32
[thirdparty/gcc.git] / gcc / config / aarch64 / aarch64-c.c
CommitLineData
e4ea20c8 1/* Target-specific code for C family languages.
99dee823 2 Copyright (C) 2015-2021 Free Software Foundation, Inc.
e4ea20c8
KT
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
8fcc61f8
RS
20#define IN_TARGET_CODE 1
21
e4ea20c8
KT
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "input.h"
4d0cdd0c 27#include "memmodel.h"
e4ea20c8
KT
28#include "tm_p.h"
29#include "flags.h"
30#include "c-family/c-common.h"
31#include "cpplib.h"
32#include "c-family/c-pragma.h"
33#include "langhooks.h"
34#include "target.h"
35
36
37#define builtin_define(TXT) cpp_define (pfile, TXT)
38#define builtin_assert(TXT) cpp_assert (pfile, TXT)
39
40
41static void
42aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
43{
44 if (def_p)
45 cpp_define (pfile, macro);
46 else
47 cpp_undef (pfile, macro);
48}
49
50/* Define the macros that we always expect to have on AArch64. */
51
52static void
53aarch64_define_unconditional_macros (cpp_reader *pfile)
54{
55 builtin_define ("__aarch64__");
56 builtin_define ("__ARM_64BIT_STATE");
57
58 builtin_define ("__ARM_ARCH_ISA_A64");
59 builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
60 builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
61
62 /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
63 as interoperability with the same arm macro. */
64 builtin_define ("__ARM_ARCH_8A");
65
786177a3
AC
66 builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
67 AARCH64_ISA_V8_R ? 'R' : 'A');
e4ea20c8
KT
68 builtin_define ("__ARM_FEATURE_CLZ");
69 builtin_define ("__ARM_FEATURE_IDIV");
70 builtin_define ("__ARM_FEATURE_UNALIGNED");
71 builtin_define ("__ARM_PCS_AAPCS64");
72 builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
1a7a35c7
RH
73
74 builtin_define ("__GCC_ASM_FLAG_OUTPUTS__");
e4ea20c8
KT
75}
76
77/* Undefine/redefine macros that depend on the current backend state and may
78 need to change when a target pragma modifies the backend state. */
79
80static void
81aarch64_update_cpp_builtins (cpp_reader *pfile)
82{
83 aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);
84
85 builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);
86
87 builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
88 flag_short_enums ? 1 : 4);
89 aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
90 aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
91 aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);
92
93 aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);
94
95 if (TARGET_FLOAT || TARGET_SIMD)
96 {
97 builtin_define_with_int_value ("__ARM_FP", 0x0E);
98 builtin_define ("__ARM_FP16_FORMAT_IEEE");
99 builtin_define ("__ARM_FP16_ARGS");
100 }
101 else
102 cpp_undef (pfile, "__ARM_FP");
103
c61465bd
MW
104 aarch64_def_or_undef (TARGET_FP_F16INST,
105 "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile);
106 aarch64_def_or_undef (TARGET_SIMD_F16INST,
107 "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile);
108
e4ea20c8
KT
109 aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
110 aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);
111
112
113 aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
1ddc47c0 114 aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile);
9d63f43b 115 aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile);
e1d5d19e 116 aarch64_def_or_undef (TARGET_JSCVT, "__ARM_FEATURE_JCVT", pfile);
e4ea20c8
KT
117
118 cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
119 cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
120 cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
121
122 switch (aarch64_cmodel)
123 {
124 case AARCH64_CMODEL_TINY:
125 case AARCH64_CMODEL_TINY_PIC:
126 builtin_define ("__AARCH64_CMODEL_TINY__");
127 break;
128 case AARCH64_CMODEL_SMALL:
129 case AARCH64_CMODEL_SMALL_PIC:
130 builtin_define ("__AARCH64_CMODEL_SMALL__");
131 break;
132 case AARCH64_CMODEL_LARGE:
133 builtin_define ("__AARCH64_CMODEL_LARGE__");
134 break;
135 default:
136 break;
137 }
138
139 aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
140 aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
141
142 aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
89c9a60c 143 aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile);
43cacb12
RS
144 aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile);
145 cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS");
146 if (TARGET_SVE)
147 {
148 int bits;
149 if (!BITS_PER_SVE_VECTOR.is_constant (&bits))
150 bits = 0;
151 builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits);
152 }
ef4af9ed 153 aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE_VECTOR_OPERATORS",
38e62001 154 pfile);
36696774
RS
155 aarch64_def_or_undef (TARGET_SVE_I8MM,
156 "__ARM_FEATURE_SVE_MATMUL_INT8", pfile);
157 aarch64_def_or_undef (TARGET_SVE_F32MM,
158 "__ARM_FEATURE_SVE_MATMUL_FP32", pfile);
159 aarch64_def_or_undef (TARGET_SVE_F64MM,
160 "__ARM_FEATURE_SVE_MATMUL_FP64", pfile);
0617e23c 161 aarch64_def_or_undef (TARGET_SVE2, "__ARM_FEATURE_SVE2", pfile);
0a09a948
RS
162 aarch64_def_or_undef (TARGET_SVE2_AES, "__ARM_FEATURE_SVE2_AES", pfile);
163 aarch64_def_or_undef (TARGET_SVE2_BITPERM,
164 "__ARM_FEATURE_SVE2_BITPERM", pfile);
165 aarch64_def_or_undef (TARGET_SVE2_SHA3, "__ARM_FEATURE_SVE2_SHA3", pfile);
166 aarch64_def_or_undef (TARGET_SVE2_SM4, "__ARM_FEATURE_SVE2_SM4", pfile);
11e554b3 167
abb3c64e 168 aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile);
27086ea3
MC
169 aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile);
170 aarch64_def_or_undef (TARGET_SHA2, "__ARM_FEATURE_SHA2", pfile);
171 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA3", pfile);
172 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA512", pfile);
173 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM3", pfile);
174 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile);
175 aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile);
176
10bd1d96 177 aarch64_def_or_undef (TARGET_FRINT, "__ARM_FEATURE_FRINT", pfile);
89626179 178 aarch64_def_or_undef (TARGET_TME, "__ARM_FEATURE_TME", pfile);
c5dc215d 179 aarch64_def_or_undef (TARGET_RNG, "__ARM_FEATURE_RNG", pfile);
ef01e6bb 180 aarch64_def_or_undef (TARGET_MEMTAG, "__ARM_FEATURE_MEMORY_TAGGING", pfile);
89626179 181
63b6808e
SN
182 aarch64_def_or_undef (aarch64_bti_enabled (),
183 "__ARM_FEATURE_BTI_DEFAULT", pfile);
184
a1faa8e2
SN
185 cpp_undef (pfile, "__ARM_FEATURE_PAC_DEFAULT");
186 if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE)
187 {
188 int v = 0;
189 if (aarch64_ra_sign_key == AARCH64_KEY_A)
190 v |= 1;
191 if (aarch64_ra_sign_key == AARCH64_KEY_B)
192 v |= 2;
193 if (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL)
194 v |= 4;
195 builtin_define_with_int_value ("__ARM_FEATURE_PAC_DEFAULT", v);
196 }
197
a93e1d5c
DZ
198 aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile);
199 aarch64_def_or_undef (TARGET_BF16_SIMD,
200 "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
201 aarch64_def_or_undef (TARGET_BF16_FP,
202 "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", pfile);
203
11e554b3
JG
204 /* Not for ACLE, but required to keep "float.h" correct if we switch
205 target between implementations that do or do not support ARMv8.2-A
206 16-bit floating-point extensions. */
207 cpp_undef (pfile, "__FLT_EVAL_METHOD__");
208 builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
209 c_flt_eval_method (true));
210 cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__");
211 builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__",
212 c_flt_eval_method (false));
e4ea20c8
KT
213}
214
215/* Implement TARGET_CPU_CPP_BUILTINS. */
216
217void
218aarch64_cpu_cpp_builtins (cpp_reader *pfile)
219{
220 aarch64_define_unconditional_macros (pfile);
221 aarch64_update_cpp_builtins (pfile);
222}
223
224/* Hook to validate the current #pragma GCC target and set the state, and
225 update the macros based on what was changed. If ARGS is NULL, then
226 POP_TARGET is used to reset the options. */
227
228static bool
229aarch64_pragma_target_parse (tree args, tree pop_target)
230{
231 /* If args is not NULL then process it and setup the target-specific
232 information that it specifies. */
233 if (args)
234 {
ab93e9b7 235 if (!aarch64_process_target_attr (args))
e4ea20c8
KT
236 return false;
237
238 aarch64_override_options_internal (&global_options);
239 }
240
241 /* args is NULL, restore to the state described in pop_target. */
242 else
243 {
244 pop_target = pop_target ? pop_target : target_option_default_node;
ba948b37 245 cl_target_option_restore (&global_options, &global_options_set,
e4ea20c8
KT
246 TREE_TARGET_OPTION (pop_target));
247 }
248
249 target_option_current_node
ba948b37 250 = build_target_option_node (&global_options, &global_options_set);
e4ea20c8
KT
251
252 aarch64_reset_previous_fndecl ();
253 /* For the definitions, ensure all newly defined macros are considered
254 as used for -Wunused-macros. There is no point warning about the
255 compiler predefined macros. */
256 cpp_options *cpp_opts = cpp_get_options (parse_in);
257 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
258 cpp_opts->warn_unused_macros = 0;
259
260 aarch64_update_cpp_builtins (parse_in);
261
262 cpp_opts->warn_unused_macros = saved_warn_unused_macros;
263
acfc1ac1
KT
264 /* If we're popping or reseting make sure to update the globals so that
265 the optab availability predicates get recomputed. */
266 if (pop_target)
267 aarch64_save_restore_target_globals (pop_target);
268
e95a988a
KT
269 /* Initialize SIMD builtins if we haven't already.
270 Set current_target_pragma to NULL for the duration so that
271 the builtin initialization code doesn't try to tag the functions
272 being built with the attributes specified by any current pragma, thus
273 going into an infinite recursion. */
274 if (TARGET_SIMD)
275 {
276 tree saved_current_target_pragma = current_target_pragma;
277 current_target_pragma = NULL;
278 aarch64_init_simd_builtins ();
279 current_target_pragma = saved_current_target_pragma;
280 }
281
e4ea20c8
KT
282 return true;
283}
284
624d0f07
RS
285/* Implement "#pragma GCC aarch64". */
286static void
287aarch64_pragma_aarch64 (cpp_reader *)
288{
289 tree x;
290 if (pragma_lex (&x) != CPP_STRING)
291 {
292 error ("%<#pragma GCC aarch64%> requires a string parameter");
293 return;
294 }
295
296 const char *name = TREE_STRING_POINTER (x);
297 if (strcmp (name, "arm_sve.h") == 0)
298 aarch64_sve::handle_arm_sve_h ();
299 else
300 error ("unknown %<#pragma GCC aarch64%> option %qs", name);
301}
302
303/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */
304static tree
305aarch64_resolve_overloaded_builtin (unsigned int uncast_location,
306 tree fndecl, void *uncast_arglist)
307{
308 vec<tree, va_gc> empty = {};
309 location_t location = (location_t) uncast_location;
310 vec<tree, va_gc> *arglist = (uncast_arglist
311 ? (vec<tree, va_gc> *) uncast_arglist
312 : &empty);
313 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
314 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
315 tree new_fndecl;
316 switch (code & AARCH64_BUILTIN_CLASS)
317 {
318 case AARCH64_BUILTIN_GENERAL:
ef01e6bb
DZ
319 return aarch64_resolve_overloaded_builtin_general (location, fndecl,
320 uncast_arglist);
624d0f07
RS
321 case AARCH64_BUILTIN_SVE:
322 new_fndecl = aarch64_sve::resolve_overloaded_builtin (location, subcode,
323 arglist);
324 break;
325 }
326 if (new_fndecl == NULL_TREE || new_fndecl == error_mark_node)
327 return new_fndecl;
328 return build_function_call_vec (location, vNULL, new_fndecl, arglist,
329 NULL, fndecl);
330}
331
332/* Implement TARGET_CHECK_BUILTIN_CALL. */
333static bool
334aarch64_check_builtin_call (location_t loc, vec<location_t> arg_loc,
335 tree fndecl, tree orig_fndecl,
336 unsigned int nargs, tree *args)
337{
338 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
339 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
340 switch (code & AARCH64_BUILTIN_CLASS)
341 {
342 case AARCH64_BUILTIN_GENERAL:
343 return true;
344
345 case AARCH64_BUILTIN_SVE:
346 return aarch64_sve::check_builtin_call (loc, arg_loc, subcode,
347 orig_fndecl, nargs, args);
348 }
349 gcc_unreachable ();
350}
351
e4ea20c8
KT
352/* Implement REGISTER_TARGET_PRAGMAS. */
353
354void
355aarch64_register_pragmas (void)
356{
357 /* Update pragma hook to allow parsing #pragma GCC target. */
358 targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
624d0f07
RS
359
360 targetm.resolve_overloaded_builtin = aarch64_resolve_overloaded_builtin;
361 targetm.check_builtin_call = aarch64_check_builtin_call;
362
363 c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64);
e4ea20c8 364}