]>
Commit | Line | Data |
---|---|---|
e4ea20c8 | 1 | /* Target-specific code for C family languages. |
cbe34bb5 | 2 | Copyright (C) 2015-2017 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 | ||
20 | #include "config.h" | |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
23 | #include "tm.h" | |
24 | #include "input.h" | |
4d0cdd0c | 25 | #include "memmodel.h" |
e4ea20c8 KT |
26 | #include "tm_p.h" |
27 | #include "flags.h" | |
28 | #include "c-family/c-common.h" | |
29 | #include "cpplib.h" | |
30 | #include "c-family/c-pragma.h" | |
31 | #include "langhooks.h" | |
32 | #include "target.h" | |
33 | ||
34 | ||
35 | #define builtin_define(TXT) cpp_define (pfile, TXT) | |
36 | #define builtin_assert(TXT) cpp_assert (pfile, TXT) | |
37 | ||
38 | ||
39 | static void | |
40 | aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile) | |
41 | { | |
42 | if (def_p) | |
43 | cpp_define (pfile, macro); | |
44 | else | |
45 | cpp_undef (pfile, macro); | |
46 | } | |
47 | ||
48 | /* Define the macros that we always expect to have on AArch64. */ | |
49 | ||
50 | static void | |
51 | aarch64_define_unconditional_macros (cpp_reader *pfile) | |
52 | { | |
53 | builtin_define ("__aarch64__"); | |
54 | builtin_define ("__ARM_64BIT_STATE"); | |
55 | ||
56 | builtin_define ("__ARM_ARCH_ISA_A64"); | |
57 | builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28); | |
58 | builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16); | |
59 | ||
60 | /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally | |
61 | as interoperability with the same arm macro. */ | |
62 | builtin_define ("__ARM_ARCH_8A"); | |
63 | ||
64 | builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A'); | |
65 | builtin_define ("__ARM_FEATURE_CLZ"); | |
66 | builtin_define ("__ARM_FEATURE_IDIV"); | |
67 | builtin_define ("__ARM_FEATURE_UNALIGNED"); | |
68 | builtin_define ("__ARM_PCS_AAPCS64"); | |
69 | builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8); | |
70 | } | |
71 | ||
72 | /* Undefine/redefine macros that depend on the current backend state and may | |
73 | need to change when a target pragma modifies the backend state. */ | |
74 | ||
75 | static void | |
76 | aarch64_update_cpp_builtins (cpp_reader *pfile) | |
77 | { | |
78 | aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile); | |
79 | ||
80 | builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version); | |
81 | ||
82 | builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM", | |
83 | flag_short_enums ? 1 : 4); | |
84 | aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile); | |
85 | aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile); | |
86 | aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile); | |
87 | ||
88 | aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile); | |
89 | ||
90 | if (TARGET_FLOAT || TARGET_SIMD) | |
91 | { | |
92 | builtin_define_with_int_value ("__ARM_FP", 0x0E); | |
93 | builtin_define ("__ARM_FP16_FORMAT_IEEE"); | |
94 | builtin_define ("__ARM_FP16_ARGS"); | |
95 | } | |
96 | else | |
97 | cpp_undef (pfile, "__ARM_FP"); | |
98 | ||
c61465bd MW |
99 | aarch64_def_or_undef (TARGET_FP_F16INST, |
100 | "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile); | |
101 | aarch64_def_or_undef (TARGET_SIMD_F16INST, | |
102 | "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile); | |
103 | ||
e4ea20c8 KT |
104 | aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile); |
105 | aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile); | |
106 | ||
107 | ||
108 | aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile); | |
109 | ||
110 | cpp_undef (pfile, "__AARCH64_CMODEL_TINY__"); | |
111 | cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__"); | |
112 | cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__"); | |
113 | ||
114 | switch (aarch64_cmodel) | |
115 | { | |
116 | case AARCH64_CMODEL_TINY: | |
117 | case AARCH64_CMODEL_TINY_PIC: | |
118 | builtin_define ("__AARCH64_CMODEL_TINY__"); | |
119 | break; | |
120 | case AARCH64_CMODEL_SMALL: | |
121 | case AARCH64_CMODEL_SMALL_PIC: | |
122 | builtin_define ("__AARCH64_CMODEL_SMALL__"); | |
123 | break; | |
124 | case AARCH64_CMODEL_LARGE: | |
125 | builtin_define ("__AARCH64_CMODEL_LARGE__"); | |
126 | break; | |
127 | default: | |
128 | break; | |
129 | } | |
130 | ||
131 | aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile); | |
132 | aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile); | |
133 | ||
134 | aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile); | |
89c9a60c | 135 | aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile); |
11e554b3 JG |
136 | |
137 | /* Not for ACLE, but required to keep "float.h" correct if we switch | |
138 | target between implementations that do or do not support ARMv8.2-A | |
139 | 16-bit floating-point extensions. */ | |
140 | cpp_undef (pfile, "__FLT_EVAL_METHOD__"); | |
141 | builtin_define_with_int_value ("__FLT_EVAL_METHOD__", | |
142 | c_flt_eval_method (true)); | |
143 | cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__"); | |
144 | builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__", | |
145 | c_flt_eval_method (false)); | |
e4ea20c8 KT |
146 | } |
147 | ||
148 | /* Implement TARGET_CPU_CPP_BUILTINS. */ | |
149 | ||
150 | void | |
151 | aarch64_cpu_cpp_builtins (cpp_reader *pfile) | |
152 | { | |
153 | aarch64_define_unconditional_macros (pfile); | |
154 | aarch64_update_cpp_builtins (pfile); | |
155 | } | |
156 | ||
157 | /* Hook to validate the current #pragma GCC target and set the state, and | |
158 | update the macros based on what was changed. If ARGS is NULL, then | |
159 | POP_TARGET is used to reset the options. */ | |
160 | ||
161 | static bool | |
162 | aarch64_pragma_target_parse (tree args, tree pop_target) | |
163 | { | |
164 | /* If args is not NULL then process it and setup the target-specific | |
165 | information that it specifies. */ | |
166 | if (args) | |
167 | { | |
168 | if (!aarch64_process_target_attr (args, "pragma")) | |
169 | return false; | |
170 | ||
171 | aarch64_override_options_internal (&global_options); | |
172 | } | |
173 | ||
174 | /* args is NULL, restore to the state described in pop_target. */ | |
175 | else | |
176 | { | |
177 | pop_target = pop_target ? pop_target : target_option_default_node; | |
178 | cl_target_option_restore (&global_options, | |
179 | TREE_TARGET_OPTION (pop_target)); | |
180 | } | |
181 | ||
182 | target_option_current_node | |
183 | = build_target_option_node (&global_options); | |
184 | ||
185 | aarch64_reset_previous_fndecl (); | |
186 | /* For the definitions, ensure all newly defined macros are considered | |
187 | as used for -Wunused-macros. There is no point warning about the | |
188 | compiler predefined macros. */ | |
189 | cpp_options *cpp_opts = cpp_get_options (parse_in); | |
190 | unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros; | |
191 | cpp_opts->warn_unused_macros = 0; | |
192 | ||
193 | aarch64_update_cpp_builtins (parse_in); | |
194 | ||
195 | cpp_opts->warn_unused_macros = saved_warn_unused_macros; | |
196 | ||
acfc1ac1 KT |
197 | /* If we're popping or reseting make sure to update the globals so that |
198 | the optab availability predicates get recomputed. */ | |
199 | if (pop_target) | |
200 | aarch64_save_restore_target_globals (pop_target); | |
201 | ||
e95a988a KT |
202 | /* Initialize SIMD builtins if we haven't already. |
203 | Set current_target_pragma to NULL for the duration so that | |
204 | the builtin initialization code doesn't try to tag the functions | |
205 | being built with the attributes specified by any current pragma, thus | |
206 | going into an infinite recursion. */ | |
207 | if (TARGET_SIMD) | |
208 | { | |
209 | tree saved_current_target_pragma = current_target_pragma; | |
210 | current_target_pragma = NULL; | |
211 | aarch64_init_simd_builtins (); | |
212 | current_target_pragma = saved_current_target_pragma; | |
213 | } | |
214 | ||
e4ea20c8 KT |
215 | return true; |
216 | } | |
217 | ||
218 | /* Implement REGISTER_TARGET_PRAGMAS. */ | |
219 | ||
220 | void | |
221 | aarch64_register_pragmas (void) | |
222 | { | |
223 | /* Update pragma hook to allow parsing #pragma GCC target. */ | |
224 | targetm.target_option.pragma_parse = aarch64_pragma_target_parse; | |
225 | } |