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