]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm-c.c
[arm][2/3] Implement fp16fml extension for ARMv8.4-A
[thirdparty/gcc.git] / gcc / config / arm / arm-c.c
1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
18
19 #define IN_TARGET_CODE 1
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "target.h"
25 #include "c-family/c-common.h"
26 #include "memmodel.h"
27 #include "tm_p.h"
28 #include "c-family/c-pragma.h"
29 #include "stringpool.h"
30
31 /* Output C specific EABI object attributes. These can not be done in
32 arm.c because they require information from the C frontend. */
33
34 static void
35 arm_output_c_attributes (void)
36 {
37 int wchar_size = (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT);
38 arm_emit_eabi_attribute ("Tag_ABI_PCS_wchar_t", 18, wchar_size);
39 }
40
41
42 /* Setup so that common code calls arm_output_c_attributes. */
43
44 void
45 arm_lang_object_attributes_init (void)
46 {
47 arm_lang_output_object_attributes_hook = arm_output_c_attributes;
48 }
49
50 #define builtin_define(TXT) cpp_define (pfile, TXT)
51 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
52
53 /* Define or undefine macros based on the current target. If the user does
54 #pragma GCC target, we need to adjust the macros dynamically. */
55
56 static void
57 def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p)
58 {
59 if (def_p)
60 cpp_define (pfile, name);
61 else
62 cpp_undef (pfile, name);
63 }
64
65 static void
66 arm_cpu_builtins (struct cpp_reader* pfile)
67 {
68 def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
69 def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
70 def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
71 def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO);
72
73 def_or_undef_macro (pfile, "__ARM_FEATURE_UNALIGNED", unaligned_access);
74
75 def_or_undef_macro (pfile, "__ARM_FEATURE_QRDMX", TARGET_NEON_RDMA);
76
77 def_or_undef_macro (pfile, "__ARM_FEATURE_CRC32", TARGET_CRC32);
78 def_or_undef_macro (pfile, "__ARM_FEATURE_DOTPROD", TARGET_DOTPROD);
79 def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
80
81 cpp_undef (pfile, "__ARM_FEATURE_CMSE");
82 if (arm_arch8 && !arm_arch_notm)
83 {
84 if (arm_arch_cmse && use_cmse)
85 builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
86 else
87 builtin_define ("__ARM_FEATURE_CMSE");
88 }
89
90 if (TARGET_ARM_FEATURE_LDREX)
91 builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
92 TARGET_ARM_FEATURE_LDREX);
93 else
94 cpp_undef (pfile, "__ARM_FEATURE_LDREX");
95
96 def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ",
97 ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB)
98 || TARGET_ARM_ARCH_ISA_THUMB >=2));
99
100 def_or_undef_macro (pfile, "__ARM_FEATURE_NUMERIC_MAXMIN",
101 TARGET_ARM_ARCH >= 8 && TARGET_NEON && TARGET_VFP5);
102
103 def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD);
104
105 builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
106 flag_short_enums ? 1 : 4);
107 builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node);
108 if (TARGET_ARM_ARCH_PROFILE)
109 builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
110 TARGET_ARM_ARCH_PROFILE);
111
112 /* Define __arm__ even when in thumb mode, for
113 consistency with armcc. */
114 builtin_define ("__arm__");
115 if (TARGET_ARM_ARCH)
116 builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
117 if (arm_arch_notm)
118 builtin_define ("__ARM_ARCH_ISA_ARM");
119 builtin_define ("__APCS_32__");
120
121 def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
122 def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
123 if (TARGET_BIG_END)
124 def_or_undef_macro (pfile, "__THUMBEB__", TARGET_THUMB);
125 else
126 def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB);
127
128 if (TARGET_ARM_ARCH_ISA_THUMB)
129 builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB",
130 TARGET_ARM_ARCH_ISA_THUMB);
131
132 if (TARGET_BIG_END)
133 {
134 builtin_define ("__ARMEB__");
135 builtin_define ("__ARM_BIG_ENDIAN");
136 }
137 else
138 {
139 builtin_define ("__ARMEL__");
140 }
141
142 if (TARGET_SOFT_FLOAT)
143 builtin_define ("__SOFTFP__");
144
145 builtin_define ("__VFP_FP__");
146
147 if (TARGET_ARM_FP)
148 builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
149 else
150 cpp_undef (pfile, "__ARM_FP");
151
152 def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
153 arm_fp16_format == ARM_FP16_FORMAT_IEEE);
154 def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
155 arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
156 def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
157 arm_fp16_format != ARM_FP16_FORMAT_NONE);
158
159 def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
160 TARGET_VFP_FP16INST);
161 def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
162 TARGET_NEON_FP16INST);
163 def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_FML", TARGET_FP16FML);
164
165 def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
166 def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
167 def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
168
169 if (TARGET_NEON_FP)
170 builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
171 else
172 cpp_undef (pfile, "__ARM_NEON_FP");
173
174 /* Add a define for interworking. Needed when building libgcc.a. */
175 if (arm_cpp_interwork)
176 builtin_define ("__THUMB_INTERWORK__");
177
178 builtin_define (arm_arch_name);
179 if (arm_arch_xscale)
180 builtin_define ("__XSCALE__");
181 if (arm_arch_iwmmxt)
182 {
183 builtin_define ("__IWMMXT__");
184 builtin_define ("__ARM_WMMX");
185 }
186 if (arm_arch_iwmmxt2)
187 builtin_define ("__IWMMXT2__");
188 /* ARMv6KZ was originally identified as the misspelled __ARM_ARCH_6ZK__. To
189 preserve the existing behavior, the misspelled feature macro must still be
190 defined. */
191 if (arm_arch6kz)
192 builtin_define ("__ARM_ARCH_6ZK__");
193 if (TARGET_AAPCS_BASED)
194 {
195 if (arm_pcs_default == ARM_PCS_AAPCS_VFP)
196 builtin_define ("__ARM_PCS_VFP");
197 else if (arm_pcs_default == ARM_PCS_AAPCS)
198 builtin_define ("__ARM_PCS");
199 builtin_define ("__ARM_EABI__");
200 }
201
202 def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
203 def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
204
205 def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
206
207 if (TARGET_32BIT && arm_arch4 && !(arm_arch8 && arm_arch_notm))
208 {
209 int coproc_level = 0x1;
210
211 if (arm_arch5)
212 coproc_level |= 0x2;
213 if (arm_arch5e)
214 coproc_level |= 0x4;
215 if (arm_arch6)
216 coproc_level |= 0x8;
217
218 builtin_define_with_int_value ("__ARM_FEATURE_COPROC", coproc_level);
219 }
220 else
221 cpp_undef (pfile, "__ARM_FEATURE_COPROC");
222 }
223
224 void
225 arm_cpu_cpp_builtins (struct cpp_reader * pfile)
226 {
227 builtin_assert ("cpu=arm");
228 builtin_assert ("machine=arm");
229
230 arm_cpu_builtins (pfile);
231 }
232
233 /* Hook to validate the current #pragma GCC target and set the arch custom
234 mode state. If ARGS is NULL, then POP_TARGET is used to reset
235 the options. */
236
237 static bool
238 arm_pragma_target_parse (tree args, tree pop_target)
239 {
240 tree prev_tree = target_option_current_node;
241 tree cur_tree;
242 struct cl_target_option *prev_opt;
243 struct cl_target_option *cur_opt;
244
245 if (! args)
246 {
247 cur_tree = ((pop_target) ? pop_target : target_option_default_node);
248 cl_target_option_restore (&global_options,
249 TREE_TARGET_OPTION (cur_tree));
250 }
251 else
252 {
253 cur_tree = arm_valid_target_attribute_tree (args, &global_options,
254 &global_options_set);
255 if (cur_tree == NULL_TREE)
256 {
257 cl_target_option_restore (&global_options,
258 TREE_TARGET_OPTION (prev_tree));
259 return false;
260 }
261
262 /* handle_pragma_pop_options and handle_pragma_reset_options will set
263 target_option_current_node, but not handle_pragma_target. */
264 target_option_current_node = cur_tree;
265 arm_configure_build_target (&arm_active_target,
266 TREE_TARGET_OPTION (cur_tree),
267 &global_options_set, false);
268 }
269
270 /* Update macros if target_node changes. The global state will be restored
271 by arm_set_current_function. */
272 prev_opt = TREE_TARGET_OPTION (prev_tree);
273 cur_opt = TREE_TARGET_OPTION (cur_tree);
274
275 gcc_assert (prev_opt);
276 gcc_assert (cur_opt);
277
278 if (cur_opt != prev_opt)
279 {
280 /* For the definitions, ensure all newly defined macros are considered
281 as used for -Wunused-macros. There is no point warning about the
282 compiler predefined macros. */
283 cpp_options *cpp_opts = cpp_get_options (parse_in);
284 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
285
286 cpp_opts->warn_unused_macros = 0;
287
288 /* Update macros. */
289 gcc_assert (cur_opt->x_target_flags == target_flags);
290
291 /* Don't warn for macros that have context sensitive values depending on
292 other attributes.
293 See warn_of_redefinition, reset after cpp_create_definition. */
294 tree acond_macro = get_identifier ("__ARM_NEON_FP");
295 C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL ;
296
297 acond_macro = get_identifier ("__ARM_FP");
298 C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
299
300 acond_macro = get_identifier ("__ARM_FEATURE_LDREX");
301 C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
302
303 arm_cpu_builtins (parse_in);
304
305 cpp_opts->warn_unused_macros = saved_warn_unused_macros;
306
307 /* Make sure that target_reinit is called for next function, since
308 TREE_TARGET_OPTION might change with the #pragma even if there is
309 no target attribute attached to the function. */
310 arm_reset_previous_fndecl ();
311
312 /* If going to the default mode, we restore the initial states.
313 if cur_tree is a new target, states will be saved/restored on a per
314 function basis in arm_set_current_function. */
315 if (cur_tree == target_option_default_node)
316 save_restore_target_globals (cur_tree);
317 }
318
319 return true;
320 }
321
322 /* Register target pragmas. We need to add the hook for parsing #pragma GCC
323 option here rather than in arm.c since it will pull in various preprocessor
324 functions, and those are not present in languages like fortran without a
325 preprocessor. */
326
327 void
328 arm_register_target_pragmas (void)
329 {
330 /* Update pragma hook to allow parsing #pragma GCC target. */
331 targetm.target_option.pragma_parse = arm_pragma_target_parse;
332
333 #ifdef REGISTER_SUBTARGET_PRAGMAS
334 REGISTER_SUBTARGET_PRAGMAS ();
335 #endif
336 }