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