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