1 /* Target-specific code for C family languages.
2 Copyright (C) 2015-2018 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
aarch64_def_or_undef(bool def_p,const char * macro,cpp_reader * pfile)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
aarch64_define_unconditional_macros(cpp_reader * pfile)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
aarch64_update_cpp_builtins(cpp_reader * pfile)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
113 cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
114 cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
115 cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
116
117 switch (aarch64_cmodel)
118 {
119 case AARCH64_CMODEL_TINY:
120 case AARCH64_CMODEL_TINY_PIC:
121 builtin_define ("__AARCH64_CMODEL_TINY__");
122 break;
123 case AARCH64_CMODEL_SMALL:
124 case AARCH64_CMODEL_SMALL_PIC:
125 builtin_define ("__AARCH64_CMODEL_SMALL__");
126 break;
127 case AARCH64_CMODEL_LARGE:
128 builtin_define ("__AARCH64_CMODEL_LARGE__");
129 break;
130 default:
131 break;
132 }
133
134 aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
135 aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
136
137 aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
138 aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile);
139 aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile);
140 cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS");
141 if (TARGET_SVE)
142 {
143 int bits;
144 if (!BITS_PER_SVE_VECTOR.is_constant (&bits))
145 bits = 0;
146 builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits);
147 }
148
149 aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile);
150 aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile);
151 aarch64_def_or_undef (TARGET_SHA2, "__ARM_FEATURE_SHA2", pfile);
152 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA3", pfile);
153 aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA512", pfile);
154 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM3", pfile);
155 aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile);
156 aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile);
157
158 /* Not for ACLE, but required to keep "float.h" correct if we switch
159 target between implementations that do or do not support ARMv8.2-A
160 16-bit floating-point extensions. */
161 cpp_undef (pfile, "__FLT_EVAL_METHOD__");
162 builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
163 c_flt_eval_method (true));
164 cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__");
165 builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__",
166 c_flt_eval_method (false));
167 }
168
169 /* Implement TARGET_CPU_CPP_BUILTINS. */
170
171 void
aarch64_cpu_cpp_builtins(cpp_reader * pfile)172 aarch64_cpu_cpp_builtins (cpp_reader *pfile)
173 {
174 aarch64_define_unconditional_macros (pfile);
175 aarch64_update_cpp_builtins (pfile);
176 }
177
178 /* Hook to validate the current #pragma GCC target and set the state, and
179 update the macros based on what was changed. If ARGS is NULL, then
180 POP_TARGET is used to reset the options. */
181
182 static bool
aarch64_pragma_target_parse(tree args,tree pop_target)183 aarch64_pragma_target_parse (tree args, tree pop_target)
184 {
185 /* If args is not NULL then process it and setup the target-specific
186 information that it specifies. */
187 if (args)
188 {
189 if (!aarch64_process_target_attr (args))
190 return false;
191
192 aarch64_override_options_internal (&global_options);
193 }
194
195 /* args is NULL, restore to the state described in pop_target. */
196 else
197 {
198 pop_target = pop_target ? pop_target : target_option_default_node;
199 cl_target_option_restore (&global_options,
200 TREE_TARGET_OPTION (pop_target));
201 }
202
203 target_option_current_node
204 = build_target_option_node (&global_options);
205
206 aarch64_reset_previous_fndecl ();
207 /* For the definitions, ensure all newly defined macros are considered
208 as used for -Wunused-macros. There is no point warning about the
209 compiler predefined macros. */
210 cpp_options *cpp_opts = cpp_get_options (parse_in);
211 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
212 cpp_opts->warn_unused_macros = 0;
213
214 aarch64_update_cpp_builtins (parse_in);
215
216 cpp_opts->warn_unused_macros = saved_warn_unused_macros;
217
218 /* If we're popping or reseting make sure to update the globals so that
219 the optab availability predicates get recomputed. */
220 if (pop_target)
221 aarch64_save_restore_target_globals (pop_target);
222
223 /* Initialize SIMD builtins if we haven't already.
224 Set current_target_pragma to NULL for the duration so that
225 the builtin initialization code doesn't try to tag the functions
226 being built with the attributes specified by any current pragma, thus
227 going into an infinite recursion. */
228 if (TARGET_SIMD)
229 {
230 tree saved_current_target_pragma = current_target_pragma;
231 current_target_pragma = NULL;
232 aarch64_init_simd_builtins ();
233 current_target_pragma = saved_current_target_pragma;
234 }
235
236 return true;
237 }
238
239 /* Implement REGISTER_TARGET_PRAGMAS. */
240
241 void
aarch64_register_pragmas(void)242 aarch64_register_pragmas (void)
243 {
244 /* Update pragma hook to allow parsing #pragma GCC target. */
245 targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
246 }
247