1 /* Target-specific code for C family languages. 2 Copyright (C) 2015-2019 Free Software Foundation, Inc. 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 20 #define IN_TARGET_CODE 1 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "tm.h" 26 #include "input.h" 27 #include "memmodel.h" 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 41 static void 42 aarch64_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 52 static void 53 aarch64_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 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); 72 } 73 74 /* Undefine/redefine macros that depend on the current backend state and may 75 need to change when a target pragma modifies the backend state. */ 76 77 static void 78 aarch64_update_cpp_builtins (cpp_reader *pfile) 79 { 80 aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile); 81 82 builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version); 83 84 builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM", 85 flag_short_enums ? 1 : 4); 86 aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile); 87 aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile); 88 aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile); 89 90 aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile); 91 92 if (TARGET_FLOAT || TARGET_SIMD) 93 { 94 builtin_define_with_int_value ("__ARM_FP", 0x0E); 95 builtin_define ("__ARM_FP16_FORMAT_IEEE"); 96 builtin_define ("__ARM_FP16_ARGS"); 97 } 98 else 99 cpp_undef (pfile, "__ARM_FP"); 100 101 aarch64_def_or_undef (TARGET_FP_F16INST, 102 "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile); 103 aarch64_def_or_undef (TARGET_SIMD_F16INST, 104 "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile); 105 106 aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile); 107 aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile); 108 109 110 aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile); 111 aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile); 112 aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile); 113 114 cpp_undef (pfile, "__AARCH64_CMODEL_TINY__"); 115 cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__"); 116 cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__"); 117 118 switch (aarch64_cmodel) 119 { 120 case AARCH64_CMODEL_TINY: 121 case AARCH64_CMODEL_TINY_PIC: 122 builtin_define ("__AARCH64_CMODEL_TINY__"); 123 break; 124 case AARCH64_CMODEL_SMALL: 125 case AARCH64_CMODEL_SMALL_PIC: 126 builtin_define ("__AARCH64_CMODEL_SMALL__"); 127 break; 128 case AARCH64_CMODEL_LARGE: 129 builtin_define ("__AARCH64_CMODEL_LARGE__"); 130 break; 131 default: 132 break; 133 } 134 135 aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile); 136 aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile); 137 138 aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile); 139 aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile); 140 aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile); 141 cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS"); 142 if (TARGET_SVE) 143 { 144 int bits; 145 if (!BITS_PER_SVE_VECTOR.is_constant (&bits)) 146 bits = 0; 147 builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits); 148 } 149 150 aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile); 151 aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile); 152 aarch64_def_or_undef (TARGET_SHA2, "__ARM_FEATURE_SHA2", pfile); 153 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA3", pfile); 154 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA512", pfile); 155 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM3", pfile); 156 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile); 157 aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile); 158 159 /* Not for ACLE, but required to keep "float.h" correct if we switch 160 target between implementations that do or do not support ARMv8.2-A 161 16-bit floating-point extensions. */ 162 cpp_undef (pfile, "__FLT_EVAL_METHOD__"); 163 builtin_define_with_int_value ("__FLT_EVAL_METHOD__", 164 c_flt_eval_method (true)); 165 cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__"); 166 builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__", 167 c_flt_eval_method (false)); 168 } 169 170 /* Implement TARGET_CPU_CPP_BUILTINS. */ 171 172 void 173 aarch64_cpu_cpp_builtins (cpp_reader *pfile) 174 { 175 aarch64_define_unconditional_macros (pfile); 176 aarch64_update_cpp_builtins (pfile); 177 } 178 179 /* Hook to validate the current #pragma GCC target and set the state, and 180 update the macros based on what was changed. If ARGS is NULL, then 181 POP_TARGET is used to reset the options. */ 182 183 static bool 184 aarch64_pragma_target_parse (tree args, tree pop_target) 185 { 186 /* If args is not NULL then process it and setup the target-specific 187 information that it specifies. */ 188 if (args) 189 { 190 if (!aarch64_process_target_attr (args)) 191 return false; 192 193 aarch64_override_options_internal (&global_options); 194 } 195 196 /* args is NULL, restore to the state described in pop_target. */ 197 else 198 { 199 pop_target = pop_target ? pop_target : target_option_default_node; 200 cl_target_option_restore (&global_options, 201 TREE_TARGET_OPTION (pop_target)); 202 } 203 204 target_option_current_node 205 = build_target_option_node (&global_options); 206 207 aarch64_reset_previous_fndecl (); 208 /* For the definitions, ensure all newly defined macros are considered 209 as used for -Wunused-macros. There is no point warning about the 210 compiler predefined macros. */ 211 cpp_options *cpp_opts = cpp_get_options (parse_in); 212 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros; 213 cpp_opts->warn_unused_macros = 0; 214 215 aarch64_update_cpp_builtins (parse_in); 216 217 cpp_opts->warn_unused_macros = saved_warn_unused_macros; 218 219 /* If we're popping or reseting make sure to update the globals so that 220 the optab availability predicates get recomputed. */ 221 if (pop_target) 222 aarch64_save_restore_target_globals (pop_target); 223 224 /* Initialize SIMD builtins if we haven't already. 225 Set current_target_pragma to NULL for the duration so that 226 the builtin initialization code doesn't try to tag the functions 227 being built with the attributes specified by any current pragma, thus 228 going into an infinite recursion. */ 229 if (TARGET_SIMD) 230 { 231 tree saved_current_target_pragma = current_target_pragma; 232 current_target_pragma = NULL; 233 aarch64_init_simd_builtins (); 234 current_target_pragma = saved_current_target_pragma; 235 } 236 237 return true; 238 } 239 240 /* Implement REGISTER_TARGET_PRAGMAS. */ 241 242 void 243 aarch64_register_pragmas (void) 244 { 245 /* Update pragma hook to allow parsing #pragma GCC target. */ 246 targetm.target_option.pragma_parse = aarch64_pragma_target_parse; 247 } 248