1 /* Target-specific code for C family languages.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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/>. */
20 #define IN_TARGET_CODE 1
24 #include "coretypes.h"
30 #include "c-family/c-common.h"
32 #include "c-family/c-pragma.h"
33 #include "langhooks.h"
37 #define builtin_define(TXT) cpp_define (pfile, TXT)
38 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
42 aarch64_def_or_undef (bool def_p
, const char *macro
, cpp_reader
*pfile
)
45 cpp_define (pfile
, macro
);
47 cpp_undef (pfile
, macro
);
50 /* Define the macros that we always expect to have on AArch64. */
53 aarch64_define_unconditional_macros (cpp_reader
*pfile
)
55 builtin_define ("__aarch64__");
56 builtin_define ("__ARM_64BIT_STATE");
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);
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");
66 builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
67 builtin_define ("__ARM_FEATURE_CLZ");
68 builtin_define ("__ARM_FEATURE_IDIV");
69 builtin_define ("__ARM_FEATURE_UNALIGNED");
70 builtin_define ("__ARM_PCS_AAPCS64");
71 builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE
/ 8);
73 builtin_define ("__GCC_ASM_FLAG_OUTPUTS__");
76 /* Undefine/redefine macros that depend on the current backend state and may
77 need to change when a target pragma modifies the backend state. */
80 aarch64_update_cpp_builtins (cpp_reader
*pfile
)
82 aarch64_def_or_undef (flag_unsafe_math_optimizations
, "__ARM_FP_FAST", pfile
);
84 builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version
);
86 builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
87 flag_short_enums
? 1 : 4);
88 aarch64_def_or_undef (TARGET_BIG_END
, "__AARCH64EB__", pfile
);
89 aarch64_def_or_undef (TARGET_BIG_END
, "__ARM_BIG_ENDIAN", pfile
);
90 aarch64_def_or_undef (!TARGET_BIG_END
, "__AARCH64EL__", pfile
);
92 aarch64_def_or_undef (TARGET_FLOAT
, "__ARM_FEATURE_FMA", pfile
);
94 if (TARGET_FLOAT
|| TARGET_SIMD
)
96 builtin_define_with_int_value ("__ARM_FP", 0x0E);
97 builtin_define ("__ARM_FP16_FORMAT_IEEE");
98 builtin_define ("__ARM_FP16_ARGS");
101 cpp_undef (pfile
, "__ARM_FP");
103 aarch64_def_or_undef (TARGET_FP_F16INST
,
104 "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile
);
105 aarch64_def_or_undef (TARGET_SIMD_F16INST
,
106 "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile
);
108 aarch64_def_or_undef (TARGET_SIMD
, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile
);
109 aarch64_def_or_undef (TARGET_SIMD
, "__ARM_NEON", pfile
);
112 aarch64_def_or_undef (TARGET_CRC32
, "__ARM_FEATURE_CRC32", pfile
);
113 aarch64_def_or_undef (TARGET_DOTPROD
, "__ARM_FEATURE_DOTPROD", pfile
);
114 aarch64_def_or_undef (TARGET_COMPLEX
, "__ARM_FEATURE_COMPLEX", pfile
);
115 aarch64_def_or_undef (TARGET_JSCVT
, "__ARM_FEATURE_JCVT", pfile
);
117 cpp_undef (pfile
, "__AARCH64_CMODEL_TINY__");
118 cpp_undef (pfile
, "__AARCH64_CMODEL_SMALL__");
119 cpp_undef (pfile
, "__AARCH64_CMODEL_LARGE__");
121 switch (aarch64_cmodel
)
123 case AARCH64_CMODEL_TINY
:
124 case AARCH64_CMODEL_TINY_PIC
:
125 builtin_define ("__AARCH64_CMODEL_TINY__");
127 case AARCH64_CMODEL_SMALL
:
128 case AARCH64_CMODEL_SMALL_PIC
:
129 builtin_define ("__AARCH64_CMODEL_SMALL__");
131 case AARCH64_CMODEL_LARGE
:
132 builtin_define ("__AARCH64_CMODEL_LARGE__");
138 aarch64_def_or_undef (TARGET_ILP32
, "_ILP32", pfile
);
139 aarch64_def_or_undef (TARGET_ILP32
, "__ILP32__", pfile
);
141 aarch64_def_or_undef (TARGET_CRYPTO
, "__ARM_FEATURE_CRYPTO", pfile
);
142 aarch64_def_or_undef (TARGET_SIMD_RDMA
, "__ARM_FEATURE_QRDMX", pfile
);
143 aarch64_def_or_undef (TARGET_SVE
, "__ARM_FEATURE_SVE", pfile
);
144 cpp_undef (pfile
, "__ARM_FEATURE_SVE_BITS");
148 if (!BITS_PER_SVE_VECTOR
.is_constant (&bits
))
150 builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits
);
152 aarch64_def_or_undef (TARGET_SVE
, "__ARM_FEATURE_SVE_VECTOR_OPERATIONS",
154 aarch64_def_or_undef (TARGET_SVE_I8MM
,
155 "__ARM_FEATURE_SVE_MATMUL_INT8", pfile
);
156 aarch64_def_or_undef (TARGET_SVE_F32MM
,
157 "__ARM_FEATURE_SVE_MATMUL_FP32", pfile
);
158 aarch64_def_or_undef (TARGET_SVE_F64MM
,
159 "__ARM_FEATURE_SVE_MATMUL_FP64", pfile
);
160 aarch64_def_or_undef (TARGET_SVE2
, "__ARM_FEATURE_SVE2", pfile
);
161 aarch64_def_or_undef (TARGET_SVE2_AES
, "__ARM_FEATURE_SVE2_AES", pfile
);
162 aarch64_def_or_undef (TARGET_SVE2_BITPERM
,
163 "__ARM_FEATURE_SVE2_BITPERM", pfile
);
164 aarch64_def_or_undef (TARGET_SVE2_SHA3
, "__ARM_FEATURE_SVE2_SHA3", pfile
);
165 aarch64_def_or_undef (TARGET_SVE2_SM4
, "__ARM_FEATURE_SVE2_SM4", pfile
);
167 aarch64_def_or_undef (TARGET_LSE
, "__ARM_FEATURE_ATOMICS", pfile
);
168 aarch64_def_or_undef (TARGET_AES
, "__ARM_FEATURE_AES", pfile
);
169 aarch64_def_or_undef (TARGET_SHA2
, "__ARM_FEATURE_SHA2", pfile
);
170 aarch64_def_or_undef (TARGET_SHA3
, "__ARM_FEATURE_SHA3", pfile
);
171 aarch64_def_or_undef (TARGET_SHA3
, "__ARM_FEATURE_SHA512", pfile
);
172 aarch64_def_or_undef (TARGET_SM4
, "__ARM_FEATURE_SM3", pfile
);
173 aarch64_def_or_undef (TARGET_SM4
, "__ARM_FEATURE_SM4", pfile
);
174 aarch64_def_or_undef (TARGET_F16FML
, "__ARM_FEATURE_FP16_FML", pfile
);
176 aarch64_def_or_undef (TARGET_FRINT
, "__ARM_FEATURE_FRINT", pfile
);
177 aarch64_def_or_undef (TARGET_TME
, "__ARM_FEATURE_TME", pfile
);
178 aarch64_def_or_undef (TARGET_RNG
, "__ARM_FEATURE_RNG", pfile
);
179 aarch64_def_or_undef (TARGET_MEMTAG
, "__ARM_FEATURE_MEMORY_TAGGING", pfile
);
181 aarch64_def_or_undef (TARGET_I8MM
, "__ARM_FEATURE_MATMUL_INT8", pfile
);
182 aarch64_def_or_undef (TARGET_BF16_SIMD
,
183 "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile
);
184 aarch64_def_or_undef (TARGET_BF16_FP
,
185 "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", pfile
);
187 /* Not for ACLE, but required to keep "float.h" correct if we switch
188 target between implementations that do or do not support ARMv8.2-A
189 16-bit floating-point extensions. */
190 cpp_undef (pfile
, "__FLT_EVAL_METHOD__");
191 builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
192 c_flt_eval_method (true));
193 cpp_undef (pfile
, "__FLT_EVAL_METHOD_C99__");
194 builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__",
195 c_flt_eval_method (false));
198 /* Implement TARGET_CPU_CPP_BUILTINS. */
201 aarch64_cpu_cpp_builtins (cpp_reader
*pfile
)
203 aarch64_define_unconditional_macros (pfile
);
204 aarch64_update_cpp_builtins (pfile
);
207 /* Hook to validate the current #pragma GCC target and set the state, and
208 update the macros based on what was changed. If ARGS is NULL, then
209 POP_TARGET is used to reset the options. */
212 aarch64_pragma_target_parse (tree args
, tree pop_target
)
214 /* If args is not NULL then process it and setup the target-specific
215 information that it specifies. */
218 if (!aarch64_process_target_attr (args
))
221 aarch64_override_options_internal (&global_options
);
224 /* args is NULL, restore to the state described in pop_target. */
227 pop_target
= pop_target
? pop_target
: target_option_default_node
;
228 cl_target_option_restore (&global_options
,
229 TREE_TARGET_OPTION (pop_target
));
232 target_option_current_node
233 = build_target_option_node (&global_options
);
235 aarch64_reset_previous_fndecl ();
236 /* For the definitions, ensure all newly defined macros are considered
237 as used for -Wunused-macros. There is no point warning about the
238 compiler predefined macros. */
239 cpp_options
*cpp_opts
= cpp_get_options (parse_in
);
240 unsigned char saved_warn_unused_macros
= cpp_opts
->warn_unused_macros
;
241 cpp_opts
->warn_unused_macros
= 0;
243 aarch64_update_cpp_builtins (parse_in
);
245 cpp_opts
->warn_unused_macros
= saved_warn_unused_macros
;
247 /* If we're popping or reseting make sure to update the globals so that
248 the optab availability predicates get recomputed. */
250 aarch64_save_restore_target_globals (pop_target
);
252 /* Initialize SIMD builtins if we haven't already.
253 Set current_target_pragma to NULL for the duration so that
254 the builtin initialization code doesn't try to tag the functions
255 being built with the attributes specified by any current pragma, thus
256 going into an infinite recursion. */
259 tree saved_current_target_pragma
= current_target_pragma
;
260 current_target_pragma
= NULL
;
261 aarch64_init_simd_builtins ();
262 current_target_pragma
= saved_current_target_pragma
;
268 /* Implement "#pragma GCC aarch64". */
270 aarch64_pragma_aarch64 (cpp_reader
*)
273 if (pragma_lex (&x
) != CPP_STRING
)
275 error ("%<#pragma GCC aarch64%> requires a string parameter");
279 const char *name
= TREE_STRING_POINTER (x
);
280 if (strcmp (name
, "arm_sve.h") == 0)
281 aarch64_sve::handle_arm_sve_h ();
283 error ("unknown %<#pragma GCC aarch64%> option %qs", name
);
286 /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */
288 aarch64_resolve_overloaded_builtin (unsigned int uncast_location
,
289 tree fndecl
, void *uncast_arglist
)
291 vec
<tree
, va_gc
> empty
= {};
292 location_t location
= (location_t
) uncast_location
;
293 vec
<tree
, va_gc
> *arglist
= (uncast_arglist
294 ? (vec
<tree
, va_gc
> *) uncast_arglist
296 unsigned int code
= DECL_MD_FUNCTION_CODE (fndecl
);
297 unsigned int subcode
= code
>> AARCH64_BUILTIN_SHIFT
;
299 switch (code
& AARCH64_BUILTIN_CLASS
)
301 case AARCH64_BUILTIN_GENERAL
:
302 return aarch64_resolve_overloaded_builtin_general (location
, fndecl
,
304 case AARCH64_BUILTIN_SVE
:
305 new_fndecl
= aarch64_sve::resolve_overloaded_builtin (location
, subcode
,
309 if (new_fndecl
== NULL_TREE
|| new_fndecl
== error_mark_node
)
311 return build_function_call_vec (location
, vNULL
, new_fndecl
, arglist
,
315 /* Implement TARGET_CHECK_BUILTIN_CALL. */
317 aarch64_check_builtin_call (location_t loc
, vec
<location_t
> arg_loc
,
318 tree fndecl
, tree orig_fndecl
,
319 unsigned int nargs
, tree
*args
)
321 unsigned int code
= DECL_MD_FUNCTION_CODE (fndecl
);
322 unsigned int subcode
= code
>> AARCH64_BUILTIN_SHIFT
;
323 switch (code
& AARCH64_BUILTIN_CLASS
)
325 case AARCH64_BUILTIN_GENERAL
:
328 case AARCH64_BUILTIN_SVE
:
329 return aarch64_sve::check_builtin_call (loc
, arg_loc
, subcode
,
330 orig_fndecl
, nargs
, args
);
335 /* Implement REGISTER_TARGET_PRAGMAS. */
338 aarch64_register_pragmas (void)
340 /* Update pragma hook to allow parsing #pragma GCC target. */
341 targetm
.target_option
.pragma_parse
= aarch64_pragma_target_parse
;
343 targetm
.resolve_overloaded_builtin
= aarch64_resolve_overloaded_builtin
;
344 targetm
.check_builtin_call
= aarch64_check_builtin_call
;
346 c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64
);